Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/profiler/cpu-profiler.h b/src/profiler/cpu-profiler.h
new file mode 100644
index 0000000..e5ef0ac
--- /dev/null
+++ b/src/profiler/cpu-profiler.h
@@ -0,0 +1,278 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PROFILER_CPU_PROFILER_H_
+#define V8_PROFILER_CPU_PROFILER_H_
+
+#include "src/allocation.h"
+#include "src/atomic-utils.h"
+#include "src/base/atomicops.h"
+#include "src/base/platform/time.h"
+#include "src/compiler.h"
+#include "src/locked-queue.h"
+#include "src/profiler/circular-queue.h"
+#include "src/profiler/sampler.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class CodeEntry;
+class CodeMap;
+class CompilationInfo;
+class CpuProfile;
+class CpuProfilesCollection;
+class ProfileGenerator;
+
+#define CODE_EVENTS_TYPE_LIST(V)                         \
+  V(CODE_CREATION, CodeCreateEventRecord)                \
+  V(CODE_MOVE, CodeMoveEventRecord)                      \
+  V(CODE_DISABLE_OPT, CodeDisableOptEventRecord)         \
+  V(CODE_DEOPT, CodeDeoptEventRecord)                    \
+  V(REPORT_BUILTIN, ReportBuiltinEventRecord)
+
+
+class CodeEventRecord {
+ public:
+#define DECLARE_TYPE(type, ignore) type,
+  enum Type {
+    NONE = 0,
+    CODE_EVENTS_TYPE_LIST(DECLARE_TYPE)
+    NUMBER_OF_TYPES
+  };
+#undef DECLARE_TYPE
+
+  Type type;
+  mutable unsigned order;
+};
+
+
+class CodeCreateEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  CodeEntry* entry;
+  unsigned size;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
+class CodeMoveEventRecord : public CodeEventRecord {
+ public:
+  Address from;
+  Address to;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
+class CodeDisableOptEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  const char* bailout_reason;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
+class CodeDeoptEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  const char* deopt_reason;
+  SourcePosition position;
+  size_t pc_offset;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
+class ReportBuiltinEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  Builtins::Name builtin_id;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
+class TickSampleEventRecord {
+ public:
+  // The parameterless constructor is used when we dequeue data from
+  // the ticks buffer.
+  TickSampleEventRecord() { }
+  explicit TickSampleEventRecord(unsigned order) : order(order) { }
+
+  unsigned order;
+  TickSample sample;
+};
+
+
+class CodeEventsContainer {
+ public:
+  explicit CodeEventsContainer(
+      CodeEventRecord::Type type = CodeEventRecord::NONE) {
+    generic.type = type;
+  }
+  union  {
+    CodeEventRecord generic;
+#define DECLARE_CLASS(ignore, type) type type##_;
+    CODE_EVENTS_TYPE_LIST(DECLARE_CLASS)
+#undef DECLARE_TYPE
+  };
+};
+
+
+// This class implements both the profile events processor thread and
+// methods called by event producers: VM and stack sampler threads.
+class ProfilerEventsProcessor : public base::Thread {
+ public:
+  ProfilerEventsProcessor(ProfileGenerator* generator,
+                          Sampler* sampler,
+                          base::TimeDelta period);
+  virtual ~ProfilerEventsProcessor();
+
+  // Thread control.
+  virtual void Run();
+  void StopSynchronously();
+  INLINE(bool running()) { return !!base::NoBarrier_Load(&running_); }
+  void Enqueue(const CodeEventsContainer& event);
+
+  // Puts current stack into tick sample events buffer.
+  void AddCurrentStack(Isolate* isolate);
+  void AddDeoptStack(Isolate* isolate, Address from, int fp_to_sp_delta);
+
+  // Tick sample events are filled directly in the buffer of the circular
+  // queue (because the structure is of fixed width, but usually not all
+  // stack frame entries are filled.) This method returns a pointer to the
+  // next record of the buffer.
+  inline TickSample* StartTickSample();
+  inline void FinishTickSample();
+
+  // SamplingCircularQueue has stricter alignment requirements than a normal new
+  // can fulfil, so we need to provide our own new/delete here.
+  void* operator new(size_t size);
+  void operator delete(void* ptr);
+
+ private:
+  // Called from events processing thread (Run() method.)
+  bool ProcessCodeEvent();
+
+  enum SampleProcessingResult {
+    OneSampleProcessed,
+    FoundSampleForNextCodeEvent,
+    NoSamplesInQueue
+  };
+  SampleProcessingResult ProcessOneSample();
+
+  ProfileGenerator* generator_;
+  Sampler* sampler_;
+  base::Atomic32 running_;
+  // Sampling period in microseconds.
+  const base::TimeDelta period_;
+  LockedQueue<CodeEventsContainer> events_buffer_;
+  static const size_t kTickSampleBufferSize = 1 * MB;
+  static const size_t kTickSampleQueueLength =
+      kTickSampleBufferSize / sizeof(TickSampleEventRecord);
+  SamplingCircularQueue<TickSampleEventRecord,
+                        kTickSampleQueueLength> ticks_buffer_;
+  LockedQueue<TickSampleEventRecord> ticks_from_vm_buffer_;
+  AtomicNumber<unsigned> last_code_event_id_;
+  unsigned last_processed_code_event_id_;
+};
+
+
+#define PROFILE(IsolateGetter, Call)                                        \
+  do {                                                                      \
+    Isolate* cpu_profiler_isolate = (IsolateGetter);                        \
+    v8::internal::Logger* logger = cpu_profiler_isolate->logger();          \
+    CpuProfiler* cpu_profiler = cpu_profiler_isolate->cpu_profiler();       \
+    if (logger->is_logging_code_events() || cpu_profiler->is_profiling()) { \
+      logger->Call;                                                         \
+    }                                                                       \
+  } while (false)
+
+
+class CpuProfiler : public CodeEventListener {
+ public:
+  explicit CpuProfiler(Isolate* isolate);
+
+  CpuProfiler(Isolate* isolate,
+              CpuProfilesCollection* test_collection,
+              ProfileGenerator* test_generator,
+              ProfilerEventsProcessor* test_processor);
+
+  virtual ~CpuProfiler();
+
+  void set_sampling_interval(base::TimeDelta value);
+  void StartProfiling(const char* title, bool record_samples = false);
+  void StartProfiling(String* title, bool record_samples);
+  CpuProfile* StopProfiling(const char* title);
+  CpuProfile* StopProfiling(String* title);
+  int GetProfilesCount();
+  CpuProfile* GetProfile(int index);
+  void DeleteAllProfiles();
+  void DeleteProfile(CpuProfile* profile);
+
+  // Invoked from stack sampler (thread or signal handler.)
+  inline TickSample* StartTickSample();
+  inline void FinishTickSample();
+
+  // Must be called via PROFILE macro, otherwise will crash when
+  // profiling is not enabled.
+  virtual void CallbackEvent(Name* name, Address entry_point);
+  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                               Code* code, const char* comment);
+  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                               Code* code, Name* name);
+  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
+                               SharedFunctionInfo* shared,
+                               CompilationInfo* info, Name* script_name);
+  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
+                               SharedFunctionInfo* shared,
+                               CompilationInfo* info, Name* script_name,
+                               int line, int column);
+  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                               Code* code, int args_count);
+  virtual void CodeMovingGCEvent() {}
+  virtual void CodeMoveEvent(Address from, Address to);
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared);
+  virtual void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta);
+  virtual void CodeDeleteEvent(Address from);
+  virtual void GetterCallbackEvent(Name* name, Address entry_point);
+  virtual void RegExpCodeCreateEvent(Code* code, String* source);
+  virtual void SetterCallbackEvent(Name* name, Address entry_point);
+  virtual void SharedFunctionInfoMoveEvent(Address from, Address to) {}
+
+  INLINE(bool is_profiling() const) { return is_profiling_; }
+  bool* is_profiling_address() {
+    return &is_profiling_;
+  }
+
+  ProfileGenerator* generator() const { return generator_; }
+  ProfilerEventsProcessor* processor() const { return processor_; }
+  Isolate* isolate() const { return isolate_; }
+
+ private:
+  void StartProcessorIfNotStarted();
+  void StopProcessorIfLastProfile(const char* title);
+  void StopProcessor();
+  void ResetProfiles();
+  void LogBuiltins();
+
+  Isolate* isolate_;
+  base::TimeDelta sampling_interval_;
+  CpuProfilesCollection* profiles_;
+  ProfileGenerator* generator_;
+  ProfilerEventsProcessor* processor_;
+  bool saved_is_logging_;
+  bool is_profiling_;
+
+  DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
+};
+
+}  // namespace internal
+}  // namespace v8
+
+
+#endif  // V8_PROFILER_CPU_PROFILER_H_