Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Unified Diff: src/profiler/profiler-listener.cc

Issue 2053523003: Refactor CpuProfiler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/profiler/profiler-listener.h ('k') | src/v8.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profiler/profiler-listener.cc
diff --git a/src/profiler/cpu-profiler.cc b/src/profiler/profiler-listener.cc
similarity index 41%
copy from src/profiler/cpu-profiler.cc
copy to src/profiler/profiler-listener.cc
index 65d10777355fd2ad2f176162a4fd62c857daf110..2b353e7fcc90d8055bbd54c71810bf514fe2d6c5 100644
--- a/src/profiler/cpu-profiler.cc
+++ b/src/profiler/profiler-listener.cc
@@ -1,266 +1,86 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2016 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.
-#include "src/profiler/cpu-profiler.h"
+#include "src/profiler/profiler-listener.h"
-#include "src/debug/debug.h"
#include "src/deoptimizer.h"
-#include "src/frames-inl.h"
-#include "src/locked-queue-inl.h"
-#include "src/log-inl.h"
-#include "src/profiler/cpu-profiler-inl.h"
-#include "src/vm-state-inl.h"
-
-#include "include/v8-profiler.h"
+#include "src/interpreter/source-position-table.h"
+#include "src/profiler/cpu-profiler.h"
+#include "src/profiler/profile-generator-inl.h"
namespace v8 {
namespace internal {
-static const int kProfilerStackSize = 64 * KB;
-
-
-ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator,
- sampler::Sampler* sampler,
- base::TimeDelta period)
- : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
- generator_(generator),
- sampler_(sampler),
- running_(1),
- period_(period),
- last_code_event_id_(0),
- last_processed_code_event_id_(0) {}
-
-
-ProfilerEventsProcessor::~ProfilerEventsProcessor() {}
-
-
-void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) {
- event.generic.order = last_code_event_id_.Increment(1);
- events_buffer_.Enqueue(event);
-}
-
-
-void ProfilerEventsProcessor::AddDeoptStack(Isolate* isolate, Address from,
- int fp_to_sp_delta) {
- TickSampleEventRecord record(last_code_event_id_.Value());
- RegisterState regs;
- Address fp = isolate->c_entry_fp(isolate->thread_local_top());
- regs.sp = fp - fp_to_sp_delta;
- regs.fp = fp;
- regs.pc = from;
- record.sample.Init(isolate, regs, TickSample::kSkipCEntryFrame, false);
- ticks_from_vm_buffer_.Enqueue(record);
-}
-
-void ProfilerEventsProcessor::AddCurrentStack(Isolate* isolate,
- bool update_stats) {
- TickSampleEventRecord record(last_code_event_id_.Value());
- RegisterState regs;
- StackFrameIterator it(isolate);
- if (!it.done()) {
- StackFrame* frame = it.frame();
- regs.sp = frame->sp();
- regs.fp = frame->fp();
- regs.pc = frame->pc();
- }
- record.sample.Init(isolate, regs, TickSample::kSkipCEntryFrame, update_stats);
- ticks_from_vm_buffer_.Enqueue(record);
-}
-
-
-void ProfilerEventsProcessor::StopSynchronously() {
- if (!base::NoBarrier_AtomicExchange(&running_, 0)) return;
- Join();
-}
-
-
-bool ProfilerEventsProcessor::ProcessCodeEvent() {
- CodeEventsContainer record;
- if (events_buffer_.Dequeue(&record)) {
- switch (record.generic.type) {
-#define PROFILER_TYPE_CASE(type, clss) \
- case CodeEventRecord::type: \
- record.clss##_.UpdateCodeMap(generator_->code_map()); \
- break;
-
- CODE_EVENTS_TYPE_LIST(PROFILER_TYPE_CASE)
-
-#undef PROFILER_TYPE_CASE
- default: return true; // Skip record.
- }
- last_processed_code_event_id_ = record.generic.order;
- return true;
- }
- return false;
-}
+ProfilerListener::ProfilerListener(Isolate* isolate)
+ : function_and_resource_names_(isolate->heap()) {}
-ProfilerEventsProcessor::SampleProcessingResult
- ProfilerEventsProcessor::ProcessOneSample() {
- TickSampleEventRecord record1;
- if (ticks_from_vm_buffer_.Peek(&record1) &&
- (record1.order == last_processed_code_event_id_)) {
- TickSampleEventRecord record;
- ticks_from_vm_buffer_.Dequeue(&record);
- generator_->RecordTickSample(record.sample);
- return OneSampleProcessed;
+ProfilerListener::~ProfilerListener() {
+ for (auto code_entry : code_entries_) {
+ delete code_entry;
}
-
- const TickSampleEventRecord* record = ticks_buffer_.Peek();
- if (record == NULL) {
- if (ticks_from_vm_buffer_.IsEmpty()) return NoSamplesInQueue;
- return FoundSampleForNextCodeEvent;
- }
- if (record->order != last_processed_code_event_id_) {
- return FoundSampleForNextCodeEvent;
- }
- generator_->RecordTickSample(record->sample);
- ticks_buffer_.Remove();
- return OneSampleProcessed;
-}
-
-
-void ProfilerEventsProcessor::Run() {
- while (!!base::NoBarrier_Load(&running_)) {
- base::TimeTicks nextSampleTime =
- base::TimeTicks::HighResolutionNow() + period_;
- base::TimeTicks now;
- SampleProcessingResult result;
- // Keep processing existing events until we need to do next sample
- // or the ticks buffer is empty.
- do {
- result = ProcessOneSample();
- if (result == FoundSampleForNextCodeEvent) {
- // All ticks of the current last_processed_code_event_id_ are
- // processed, proceed to the next code event.
- ProcessCodeEvent();
- }
- now = base::TimeTicks::HighResolutionNow();
- } while (result != NoSamplesInQueue && now < nextSampleTime);
-
- if (nextSampleTime > now) {
-#if V8_OS_WIN
- // Do not use Sleep on Windows as it is very imprecise.
- // Could be up to 16ms jitter, which is unacceptable for the purpose.
- while (base::TimeTicks::HighResolutionNow() < nextSampleTime) {
- }
-#else
- base::OS::Sleep(nextSampleTime - now);
-#endif
- }
-
- // Schedule next sample. sampler_ is NULL in tests.
- if (sampler_) sampler_->DoSample();
- }
-
- // Process remaining tick events.
- do {
- SampleProcessingResult result;
- do {
- result = ProcessOneSample();
- } while (result == OneSampleProcessed);
- } while (ProcessCodeEvent());
-}
-
-
-void* ProfilerEventsProcessor::operator new(size_t size) {
- return AlignedAlloc(size, V8_ALIGNOF(ProfilerEventsProcessor));
-}
-
-
-void ProfilerEventsProcessor::operator delete(void* ptr) {
- AlignedFree(ptr);
-}
-
-
-int CpuProfiler::GetProfilesCount() {
- // The count of profiles doesn't depend on a security token.
- return profiles_->profiles()->length();
-}
-
-
-CpuProfile* CpuProfiler::GetProfile(int index) {
- return profiles_->profiles()->at(index);
}
-
-void CpuProfiler::DeleteAllProfiles() {
- if (is_profiling_) StopProcessor();
- ResetProfiles();
-}
-
-
-void CpuProfiler::DeleteProfile(CpuProfile* profile) {
- profiles_->RemoveProfile(profile);
- delete profile;
- if (profiles_->profiles()->is_empty() && !is_profiling_) {
- // If this was the last profile, clean up all accessory data as well.
- ResetProfiles();
- }
-}
-
-
-void CpuProfiler::CallbackEvent(Name* name, Address entry_point) {
+void ProfilerListener::CallbackEvent(Name* name, Address entry_point) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = entry_point;
- rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG,
- profiles_->GetName(name));
+ rec->entry = NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name));
rec->size = 1;
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
- AbstractCode* code, const char* name) {
+void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, const char* name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
- rec->entry = profiles_->NewCodeEntry(
- tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
+ rec->entry = NewCodeEntry(
+ tag, GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
RecordInliningInfo(rec->entry, code);
rec->size = code->ExecutableSize();
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
- AbstractCode* code, Name* name) {
+void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, Name* name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
- rec->entry = profiles_->NewCodeEntry(
- tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
+ rec->entry = NewCodeEntry(
+ tag, GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
RecordInliningInfo(rec->entry, code);
rec->size = code->ExecutableSize();
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
- AbstractCode* code,
- SharedFunctionInfo* shared,
- Name* script_name) {
+void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code,
+ SharedFunctionInfo* shared,
+ Name* script_name) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
- rec->entry = profiles_->NewCodeEntry(
- tag, profiles_->GetFunctionName(shared->DebugName()),
- CodeEntry::kEmptyNamePrefix,
- profiles_->GetName(InferScriptName(script_name, shared)),
+ rec->entry = NewCodeEntry(
+ tag, GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix,
+ GetName(InferScriptName(script_name, shared)),
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
NULL, code->instruction_start());
RecordInliningInfo(rec->entry, code);
rec->entry->FillFunctionInfo(shared);
rec->size = code->ExecutableSize();
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
- AbstractCode* abstract_code,
- SharedFunctionInfo* shared, Name* script_name,
- int line, int column) {
+void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* abstract_code,
+ SharedFunctionInfo* shared,
+ Name* script_name, int line,
+ int column) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = abstract_code->address();
@@ -299,50 +119,50 @@ void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
}
}
}
- rec->entry = profiles_->NewCodeEntry(
- tag, profiles_->GetFunctionName(shared->DebugName()),
- CodeEntry::kEmptyNamePrefix,
- profiles_->GetName(InferScriptName(script_name, shared)), line, column,
- line_table, abstract_code->instruction_start());
+ rec->entry = NewCodeEntry(
+ tag, GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix,
+ GetName(InferScriptName(script_name, shared)), line, column, line_table,
+ abstract_code->instruction_start());
RecordInliningInfo(rec->entry, abstract_code);
RecordDeoptInlinedFrames(rec->entry, abstract_code);
rec->entry->FillFunctionInfo(shared);
rec->size = abstract_code->ExecutableSize();
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
- AbstractCode* code, int args_count) {
+void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, int args_count) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
- rec->entry = profiles_->NewCodeEntry(
- tag, profiles_->GetName(args_count), "args_count: ",
- CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
- CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
+ rec->entry = NewCodeEntry(
+ tag, GetName(args_count), "args_count: ", CodeEntry::kEmptyResourceName,
+ CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
+ NULL, code->instruction_start());
RecordInliningInfo(rec->entry, code);
rec->size = code->ExecutableSize();
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeMoveEvent(AbstractCode* from, Address to) {
+void ProfilerListener::CodeMoveEvent(AbstractCode* from, Address to) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
rec->from = from->address();
rec->to = to;
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeDisableOptEvent(AbstractCode* code,
- SharedFunctionInfo* shared) {
+void ProfilerListener::CodeDisableOptEvent(AbstractCode* code,
+ SharedFunctionInfo* shared) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
rec->start = code->address();
rec->bailout_reason = GetBailoutReason(shared->disable_optimization_reason());
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) {
+void ProfilerListener::CodeDeoptEvent(Code* code, Address pc,
+ int fp_to_sp_delta) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_DEOPT);
CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, pc);
@@ -350,52 +170,53 @@ void CpuProfiler::CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) {
rec->deopt_reason = Deoptimizer::GetDeoptReason(info.deopt_reason);
rec->position = info.position;
rec->deopt_id = info.deopt_id;
- processor_->Enqueue(evt_rec);
- processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta);
+ rec->pc = reinterpret_cast<void*>(pc);
+ rec->fp_to_sp_delta = fp_to_sp_delta;
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
+void ProfilerListener::GetterCallbackEvent(Name* name, Address entry_point) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = entry_point;
- rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG,
- profiles_->GetName(name), "get ");
+ rec->entry =
+ NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name), "get ");
rec->size = 1;
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-void CpuProfiler::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
+void ProfilerListener::RegExpCodeCreateEvent(AbstractCode* code,
+ String* source) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
- rec->entry = profiles_->NewCodeEntry(
- CodeEventListener::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ",
+ rec->entry = NewCodeEntry(
+ CodeEventListener::REG_EXP_TAG, GetName(source), "RegExp: ",
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
rec->size = code->ExecutableSize();
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-
-void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
+void ProfilerListener::SetterCallbackEvent(Name* name, Address entry_point) {
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = entry_point;
- rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG,
- profiles_->GetName(name), "set ");
+ rec->entry =
+ NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name), "set ");
rec->size = 1;
- processor_->Enqueue(evt_rec);
+ DispatchCodeEvent(evt_rec);
}
-Name* CpuProfiler::InferScriptName(Name* name, SharedFunctionInfo* info) {
+Name* ProfilerListener::InferScriptName(Name* name, SharedFunctionInfo* info) {
if (name->IsString() && String::cast(name)->length()) return name;
if (!info->script()->IsScript()) return name;
Object* source_url = Script::cast(info->script())->source_url();
return source_url->IsName() ? Name::cast(source_url) : name;
}
-void CpuProfiler::RecordInliningInfo(CodeEntry* entry,
- AbstractCode* abstract_code) {
+void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
+ AbstractCode* abstract_code) {
if (!abstract_code->IsCode()) return;
Code* code = abstract_code->GetCode();
if (code->kind() != Code::OPTIMIZED_FUNCTION) return;
@@ -428,7 +249,7 @@ void CpuProfiler::RecordInliningInfo(CodeEntry* entry,
deopt_input_data->LiteralArray()->get(shared_info_id));
if (!depth++) continue; // Skip the current function itself.
CodeEntry* inline_entry = new CodeEntry(
- entry->tag(), profiles_->GetFunctionName(shared_info->DebugName()),
+ entry->tag(), GetFunctionName(shared_info->DebugName()),
CodeEntry::kEmptyNamePrefix, entry->resource_name(),
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
@@ -442,8 +263,8 @@ void CpuProfiler::RecordInliningInfo(CodeEntry* entry,
}
}
-void CpuProfiler::RecordDeoptInlinedFrames(CodeEntry* entry,
- AbstractCode* abstract_code) {
+void ProfilerListener::RecordDeoptInlinedFrames(CodeEntry* entry,
+ AbstractCode* abstract_code) {
if (abstract_code->kind() != AbstractCode::OPTIMIZED_FUNCTION) return;
Code* code = abstract_code->GetCode();
DeoptimizationInputData* deopt_input_data =
@@ -490,148 +311,29 @@ void CpuProfiler::RecordDeoptInlinedFrames(CodeEntry* entry,
}
}
-CpuProfiler::CpuProfiler(Isolate* isolate)
- : isolate_(isolate),
- sampling_interval_(base::TimeDelta::FromMicroseconds(
- FLAG_cpu_profiler_sampling_interval)),
- profiles_(new CpuProfilesCollection(isolate)),
- is_profiling_(false) {
- profiles_->set_cpu_profiler(this);
-}
-
-CpuProfiler::CpuProfiler(Isolate* isolate, CpuProfilesCollection* test_profiles,
- ProfileGenerator* test_generator,
- ProfilerEventsProcessor* test_processor)
- : isolate_(isolate),
- sampling_interval_(base::TimeDelta::FromMicroseconds(
- FLAG_cpu_profiler_sampling_interval)),
- profiles_(test_profiles),
- generator_(test_generator),
- processor_(test_processor),
- is_profiling_(false) {
- profiles_->set_cpu_profiler(this);
-}
-
-CpuProfiler::~CpuProfiler() {
- DCHECK(!is_profiling_);
-}
-
-void CpuProfiler::set_sampling_interval(base::TimeDelta value) {
- DCHECK(!is_profiling_);
- sampling_interval_ = value;
-}
-
-void CpuProfiler::ResetProfiles() {
- profiles_.reset(new CpuProfilesCollection(isolate_));
- profiles_->set_cpu_profiler(this);
-}
-
-void CpuProfiler::CollectSample() {
- if (processor_) {
- processor_->AddCurrentStack(isolate_);
- }
-}
-
-void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
- if (profiles_->StartProfiling(title, record_samples)) {
- StartProcessorIfNotStarted();
- }
+CodeEntry* ProfilerListener::NewCodeEntry(
+ CodeEventListener::LogEventsAndTags tag, const char* name,
+ const char* name_prefix, const char* resource_name, int line_number,
+ int column_number, JITLineInfoTable* line_info, Address instruction_start) {
+ CodeEntry* code_entry =
+ new CodeEntry(tag, name, name_prefix, resource_name, line_number,
+ column_number, line_info, instruction_start);
+ code_entries_.push_back(code_entry);
+ return code_entry;
}
-
-void CpuProfiler::StartProfiling(String* title, bool record_samples) {
- StartProfiling(profiles_->GetName(title), record_samples);
- isolate_->debug()->feature_tracker()->Track(DebugFeatureTracker::kProfiler);
-}
-
-
-void CpuProfiler::StartProcessorIfNotStarted() {
- if (processor_) {
- processor_->AddCurrentStack(isolate_);
+void ProfilerListener::AddObserver(CodeEventObserver* observer) {
+ if (std::find(observers_.begin(), observers_.end(), observer) !=
+ observers_.end())
return;
- }
- Logger* logger = isolate_->logger();
- // Disable logging when using the new implementation.
- saved_is_logging_ = logger->is_logging_;
- logger->is_logging_ = false;
- sampler::Sampler* sampler = logger->sampler();
- generator_.reset(new ProfileGenerator(profiles_.get()));
- processor_.reset(new ProfilerEventsProcessor(generator_.get(), sampler,
- sampling_interval_));
- is_profiling_ = true;
- isolate_->set_is_profiling(true);
- // Enumerate stuff we already have in the heap.
- DCHECK(isolate_->heap()->HasBeenSetUp());
- isolate_->code_event_dispatcher()->AddListener(this);
- if (!FLAG_prof_browser_mode) {
- logger->LogCodeObjects();
- }
- logger->LogCompiledFunctions();
- logger->LogAccessorCallbacks();
- LogBuiltins();
- // Enable stack sampling.
- sampler->SetHasProcessingThread(true);
- sampler->IncreaseProfilingDepth();
- processor_->AddCurrentStack(isolate_);
- processor_->StartSynchronously();
-}
-
-
-CpuProfile* CpuProfiler::StopProfiling(const char* title) {
- if (!is_profiling_) return nullptr;
- StopProcessorIfLastProfile(title);
- CpuProfile* result = profiles_->StopProfiling(title);
- if (result) {
- result->Print();
- }
- return result;
+ observers_.push_back(observer);
}
-
-CpuProfile* CpuProfiler::StopProfiling(String* title) {
- if (!is_profiling_) return nullptr;
- const char* profile_title = profiles_->GetName(title);
- StopProcessorIfLastProfile(profile_title);
- return profiles_->StopProfiling(profile_title);
+void ProfilerListener::RemoveObserver(CodeEventObserver* observer) {
+ auto it = std::find(observers_.begin(), observers_.end(), observer);
+ if (it == observers_.end()) return;
+ observers_.erase(it);
}
-
-void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
- if (profiles_->IsLastProfile(title)) {
- StopProcessor();
- }
-}
-
-
-void CpuProfiler::StopProcessor() {
- Logger* logger = isolate_->logger();
- sampler::Sampler* sampler =
- reinterpret_cast<sampler::Sampler*>(logger->ticker_);
- is_profiling_ = false;
- isolate_->set_is_profiling(false);
- isolate_->code_event_dispatcher()->RemoveListener(this);
- processor_->StopSynchronously();
- processor_.reset();
- generator_.reset();
- sampler->SetHasProcessingThread(false);
- sampler->DecreaseProfilingDepth();
- logger->is_logging_ = saved_is_logging_;
-}
-
-
-void CpuProfiler::LogBuiltins() {
- Builtins* builtins = isolate_->builtins();
- DCHECK(builtins->is_initialized());
- for (int i = 0; i < Builtins::builtin_count; i++) {
- CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
- ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
- Builtins::Name id = static_cast<Builtins::Name>(i);
- rec->start = builtins->builtin(id)->address();
- rec->builtin_id = id;
- processor_->Enqueue(evt_rec);
- }
-}
-
-
} // namespace internal
} // namespace v8
« no previous file with comments | « src/profiler/profiler-listener.h ('k') | src/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698