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_