Commit cb59fc1f authored by lpy's avatar lpy Committed by Commit bot

Refactor CpuProfiler.

Currently CpuProfiler is a subclass of CodeEventListener, it listens code events
from Logger, constructs and stores CodeEventsContainer. This patch is part of
the effort to split the logic of CodeEventListener as ProfilerListener out of
the profiling functionality logic in CpuProfiler. A ProfilerListener will listen
to code events, construct code event to CodeEventsContainer and pass it to code
event handler.

The reason we refactor CpuProfiler is that eventually we want to move
CpuProfiler as part of sampler library and code event listener should stay
inside V8.

Main changes:
1. Refactored CpuProfiler into two parts, the CpuProfiler with profling
functionality and the ProfilerListener listening to code events from Logger.
2. Created CodeEventObserver and made CpuProfiler inherit from it.
ProfilerListener will have a list of observers and call CodeEventHandler once a
code event is created.
3. Moved code entry list from CodeEntry to ProfilerListener.

Minor changes:
1. Moved static code entry as part of CodeEntry.
2. Added ProfilerListener to Logger.

BUG=v8:4789

Review-Url: https://codereview.chromium.org/2053523003
Cr-Commit-Position: refs/heads/master@{#37112}
parent cbc6adc8
......@@ -1322,6 +1322,8 @@ v8_source_set("v8_base") {
"src/profiler/profile-generator-inl.h",
"src/profiler/profile-generator.cc",
"src/profiler/profile-generator.h",
"src/profiler/profiler-listener.cc",
"src/profiler/profiler-listener.h",
"src/profiler/sampling-heap-profiler.cc",
"src/profiler/sampling-heap-profiler.h",
"src/profiler/strings-storage.cc",
......
......@@ -22,6 +22,7 @@
#include "src/macro-assembler.h"
#include "src/perf-jit.h"
#include "src/profiler/cpu-profiler-inl.h"
#include "src/profiler/profiler-listener.h"
#include "src/runtime-profiler.h"
#include "src/string-stream.h"
#include "src/vm-state-inl.h"
......@@ -1789,6 +1790,8 @@ bool Logger::SetUp(Isolate* isolate) {
profiler_->Engage();
}
profiler_listener_.reset();
if (is_logging_) {
addCodeEventListener(this);
}
......@@ -1816,6 +1819,18 @@ void Logger::SetCodeEventHandler(uint32_t options,
}
}
void Logger::SetUpProfilerListener() {
if (!is_initialized_) return;
if (profiler_listener_.get() == nullptr) {
profiler_listener_.reset(new ProfilerListener(isolate_));
}
addCodeEventListener(profiler_listener_.get());
}
void Logger::TearDownProfilerListener() {
if (profiler_listener_->HasObservers()) return;
removeCodeEventListener(profiler_listener_.get());
}
sampler::Sampler* Logger::sampler() {
return ticker_;
......@@ -1860,6 +1875,10 @@ FILE* Logger::TearDown() {
jit_logger_ = NULL;
}
if (profiler_listener_.get() != nullptr) {
removeCodeEventListener(profiler_listener_.get());
}
return log_->Close();
}
......
......@@ -89,6 +89,7 @@ class JitLogger;
class PerfBasicLogger;
class LowLevelLogger;
class PerfJitLogger;
class ProfilerListener;
class Logger : public CodeEventListener {
public:
......@@ -101,8 +102,16 @@ class Logger : public CodeEventListener {
void SetCodeEventHandler(uint32_t options,
JitCodeEventHandler event_handler);
// Sets up ProfilerListener.
void SetUpProfilerListener();
// Tear down ProfilerListener if it has no observers.
void TearDownProfilerListener();
sampler::Sampler* sampler();
ProfilerListener* profiler_listener() { return profiler_listener_.get(); }
// Frees resources acquired in SetUp.
// When a temporary file is used for the log, returns its stream descriptor,
// leaving the file open.
......@@ -332,6 +341,7 @@ class Logger : public CodeEventListener {
PerfJitLogger* perf_jit_logger_;
LowLevelLogger* ll_logger_;
JitLogger* jit_logger_;
std::unique_ptr<ProfilerListener> profiler_listener_;
List<CodeEventListener*> listeners_;
// Guards against multiple calls to TearDown() that can happen in some tests.
......
This diff is collapsed.
......@@ -16,6 +16,7 @@
#include "src/libsampler/v8-sampler.h"
#include "src/locked-queue.h"
#include "src/profiler/circular-queue.h"
#include "src/profiler/profiler-listener.h"
#include "src/profiler/tick-sample.h"
namespace v8 {
......@@ -85,6 +86,8 @@ class CodeDeoptEventRecord : public CodeEventRecord {
const char* deopt_reason;
SourcePosition position;
int deopt_id;
void* pc;
int fp_to_sp_delta;
INLINE(void UpdateCodeMap(CodeMap* code_map));
};
......@@ -183,7 +186,7 @@ class ProfilerEventsProcessor : public base::Thread {
unsigned last_processed_code_event_id_;
};
class CpuProfiler : public CodeEventListener {
class CpuProfiler : public CodeEventObserver {
public:
explicit CpuProfiler(Isolate* isolate);
......@@ -204,34 +207,12 @@ class CpuProfiler : public CodeEventListener {
void DeleteAllProfiles();
void DeleteProfile(CpuProfile* profile);
void CodeEventHandler(const CodeEventsContainer& evt_rec) override;
// 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.
void CallbackEvent(Name* name, Address entry_point) override;
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
const char* comment) override;
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
Name* name) override;
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
SharedFunctionInfo* shared, Name* script_name) override;
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
SharedFunctionInfo* shared, Name* script_name, int line,
int column) override;
void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
int args_count) override;
void CodeMovingGCEvent() override {}
void CodeMoveEvent(AbstractCode* from, Address to) override;
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override;
void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) override;
void GetterCallbackEvent(Name* name, Address entry_point) override;
void RegExpCodeCreateEvent(AbstractCode* code, String* source) override;
void SetterCallbackEvent(Name* name, Address entry_point) override;
void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
bool is_profiling() const { return is_profiling_; }
ProfileGenerator* generator() const { return generator_.get(); }
......@@ -244,9 +225,6 @@ class CpuProfiler : public CodeEventListener {
void StopProcessor();
void ResetProfiles();
void LogBuiltins();
void RecordInliningInfo(CodeEntry* entry, AbstractCode* abstract_code);
void RecordDeoptInlinedFrames(CodeEntry* entry, AbstractCode* abstract_code);
Name* InferScriptName(Name* name, SharedFunctionInfo* info);
Isolate* const isolate_;
base::TimeDelta sampling_interval_;
......
......@@ -48,6 +48,41 @@ const char* const CodeEntry::kEmptyResourceName = "";
const char* const CodeEntry::kEmptyBailoutReason = "";
const char* const CodeEntry::kNoDeoptReason = "";
const char* const CodeEntry::kProgramEntryName = "(program)";
const char* const CodeEntry::kIdleEntryName = "(idle)";
const char* const CodeEntry::kGarbageCollectorEntryName = "(garbage collector)";
const char* const CodeEntry::kUnresolvedFunctionName = "(unresolved function)";
base::LazyDynamicInstance<CodeEntry, CodeEntry::ProgramEntryCreateTrait>::type
CodeEntry::kProgramEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry, CodeEntry::IdleEntryCreateTrait>::type
CodeEntry::kIdleEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry, CodeEntry::GCEntryCreateTrait>::type
CodeEntry::kGCEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry,
CodeEntry::UnresolvedEntryCreateTrait>::type
CodeEntry::kUnresolvedEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
CodeEntry* CodeEntry::ProgramEntryCreateTrait::Create() {
return new CodeEntry(Logger::FUNCTION_TAG, CodeEntry::kProgramEntryName);
}
CodeEntry* CodeEntry::IdleEntryCreateTrait::Create() {
return new CodeEntry(Logger::FUNCTION_TAG, CodeEntry::kIdleEntryName);
}
CodeEntry* CodeEntry::GCEntryCreateTrait::Create() {
return new CodeEntry(Logger::BUILTIN_TAG,
CodeEntry::kGarbageCollectorEntryName);
}
CodeEntry* CodeEntry::UnresolvedEntryCreateTrait::Create() {
return new CodeEntry(Logger::FUNCTION_TAG,
CodeEntry::kUnresolvedFunctionName);
}
CodeEntry::~CodeEntry() {
delete line_info_;
......@@ -433,15 +468,10 @@ void CodeMap::Print() {
}
CpuProfilesCollection::CpuProfilesCollection(Isolate* isolate)
: function_and_resource_names_(isolate->heap()),
: resource_names_(isolate->heap()),
profiler_(nullptr),
current_profiles_semaphore_(1) {}
static void DeleteCodeEntry(CodeEntry** entry_ptr) {
delete *entry_ptr;
}
static void DeleteCpuProfile(CpuProfile** profile_ptr) {
delete *profile_ptr;
}
......@@ -450,7 +480,6 @@ static void DeleteCpuProfile(CpuProfile** profile_ptr) {
CpuProfilesCollection::~CpuProfilesCollection() {
finished_profiles_.Iterate(DeleteCpuProfile);
current_profiles_.Iterate(DeleteCpuProfile);
code_entries_.Iterate(DeleteCodeEntry);
}
......@@ -527,37 +556,8 @@ void CpuProfilesCollection::AddPathToCurrentProfiles(
current_profiles_semaphore_.Signal();
}
CodeEntry* CpuProfilesCollection::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_.Add(code_entry);
return code_entry;
}
const char* const ProfileGenerator::kProgramEntryName =
"(program)";
const char* const ProfileGenerator::kIdleEntryName =
"(idle)";
const char* const ProfileGenerator::kGarbageCollectorEntryName =
"(garbage collector)";
const char* const ProfileGenerator::kUnresolvedFunctionName =
"(unresolved function)";
ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
: profiles_(profiles),
program_entry_(profiles->NewCodeEntry(CodeEventListener::FUNCTION_TAG,
kProgramEntryName)),
idle_entry_(profiles->NewCodeEntry(CodeEventListener::FUNCTION_TAG,
kIdleEntryName)),
gc_entry_(profiles->NewCodeEntry(CodeEventListener::BUILTIN_TAG,
kGarbageCollectorEntryName)),
unresolved_entry_(profiles->NewCodeEntry(CodeEventListener::FUNCTION_TAG,
kUnresolvedFunctionName)) {}
: profiles_(profiles) {}
void ProfileGenerator::RecordTickSample(const TickSample& sample) {
std::vector<CodeEntry*> entries;
......@@ -610,7 +610,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
// former case we don't so we simply replace the frame with
// 'unresolved' entry.
if (!sample.has_external_callback) {
entries.push_back(unresolved_entry_);
entries.push_back(CodeEntry::unresolved_entry());
}
}
}
......@@ -667,7 +667,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
switch (tag) {
case GC:
return gc_entry_;
return CodeEntry::gc_entry();
case JS:
case COMPILER:
// DOM events handlers are reported as OTHER / EXTERNAL entries.
......@@ -675,9 +675,9 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
// one bucket.
case OTHER:
case EXTERNAL:
return program_entry_;
return CodeEntry::program_entry();
case IDLE:
return idle_entry_;
return CodeEntry::idle_entry();
default: return NULL;
}
}
......
......@@ -114,7 +114,45 @@ class CodeEntry {
static const char* const kEmptyBailoutReason;
static const char* const kNoDeoptReason;
static const char* const kProgramEntryName;
static const char* const kIdleEntryName;
static const char* const kGarbageCollectorEntryName;
// Used to represent frames for which we have no reliable way to
// detect function.
static const char* const kUnresolvedFunctionName;
V8_INLINE static CodeEntry* program_entry() {
return kProgramEntry.Pointer();
}
V8_INLINE static CodeEntry* idle_entry() { return kIdleEntry.Pointer(); }
V8_INLINE static CodeEntry* gc_entry() { return kGCEntry.Pointer(); }
V8_INLINE static CodeEntry* unresolved_entry() {
return kUnresolvedEntry.Pointer();
}
private:
struct ProgramEntryCreateTrait {
static CodeEntry* Create();
};
struct IdleEntryCreateTrait {
static CodeEntry* Create();
};
struct GCEntryCreateTrait {
static CodeEntry* Create();
};
struct UnresolvedEntryCreateTrait {
static CodeEntry* Create();
};
static base::LazyDynamicInstance<CodeEntry, ProgramEntryCreateTrait>::type
kProgramEntry;
static base::LazyDynamicInstance<CodeEntry, IdleEntryCreateTrait>::type
kIdleEntry;
static base::LazyDynamicInstance<CodeEntry, GCEntryCreateTrait>::type
kGCEntry;
static base::LazyDynamicInstance<CodeEntry, UnresolvedEntryCreateTrait>::type
kUnresolvedEntry;
class TagField : public BitField<Logger::LogEventsAndTags, 0, 8> {};
class BuiltinIdField : public BitField<Builtins::Name, 8, 24> {};
......@@ -300,29 +338,10 @@ class CpuProfilesCollection {
bool StartProfiling(const char* title, bool record_samples);
CpuProfile* StopProfiling(const char* title);
List<CpuProfile*>* profiles() { return &finished_profiles_; }
const char* GetName(Name* name) {
return function_and_resource_names_.GetName(name);
}
const char* GetName(int args_count) {
return function_and_resource_names_.GetName(args_count);
}
const char* GetFunctionName(Name* name) {
return function_and_resource_names_.GetFunctionName(name);
}
const char* GetFunctionName(const char* name) {
return function_and_resource_names_.GetFunctionName(name);
}
const char* GetName(Name* name) { return resource_names_.GetName(name); }
bool IsLastProfile(const char* title);
void RemoveProfile(CpuProfile* profile);
CodeEntry* NewCodeEntry(
CodeEventListener::LogEventsAndTags tag, const char* name,
const char* name_prefix = CodeEntry::kEmptyNamePrefix,
const char* resource_name = CodeEntry::kEmptyResourceName,
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
JITLineInfoTable* line_info = NULL, Address instruction_start = NULL);
// Called from profile generator thread.
void AddPathToCurrentProfiles(base::TimeTicks timestamp,
const std::vector<CodeEntry*>& path,
......@@ -332,8 +351,7 @@ class CpuProfilesCollection {
static const int kMaxSimultaneousProfiles = 100;
private:
StringsStorage function_and_resource_names_;
List<CodeEntry*> code_entries_;
StringsStorage resource_names_;
List<CpuProfile*> finished_profiles_;
CpuProfiler* profiler_;
......@@ -353,22 +371,11 @@ class ProfileGenerator {
CodeMap* code_map() { return &code_map_; }
static const char* const kProgramEntryName;
static const char* const kIdleEntryName;
static const char* const kGarbageCollectorEntryName;
// Used to represent frames for which we have no reliable way to
// detect function.
static const char* const kUnresolvedFunctionName;
private:
CodeEntry* EntryForVMState(StateTag tag);
CpuProfilesCollection* profiles_;
CodeMap code_map_;
CodeEntry* program_entry_;
CodeEntry* idle_entry_;
CodeEntry* gc_entry_;
CodeEntry* unresolved_entry_;
DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
};
......
This diff is collapsed.
// 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.
#ifndef V8_PROFILER_PROFILER_LISTENER_H_
#define V8_PROFILER_PROFILER_LISTENER_H_
#include <vector>
#include "src/code-events.h"
#include "src/profiler/profile-generator.h"
namespace v8 {
namespace internal {
class CodeEventsContainer;
class CodeEventObserver {
public:
virtual void CodeEventHandler(const CodeEventsContainer& evt_rec) = 0;
virtual ~CodeEventObserver() {}
};
class ProfilerListener : public CodeEventListener {
public:
explicit ProfilerListener(Isolate* isolate);
~ProfilerListener() override;
void CallbackEvent(Name* name, Address entry_point) override;
void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, const char* comment) override;
void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, Name* name) override;
void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, SharedFunctionInfo* shared,
Name* script_name) override;
void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, SharedFunctionInfo* shared,
Name* script_name, int line, int column) override;
void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, int args_count) override;
void CodeMovingGCEvent() override {}
void CodeMoveEvent(AbstractCode* from, Address to) override;
void CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) override;
void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) override;
void GetterCallbackEvent(Name* name, Address entry_point) override;
void RegExpCodeCreateEvent(AbstractCode* code, String* source) override;
void SetterCallbackEvent(Name* name, Address entry_point) override;
void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
CodeEntry* NewCodeEntry(
CodeEventListener::LogEventsAndTags tag, const char* name,
const char* name_prefix = CodeEntry::kEmptyNamePrefix,
const char* resource_name = CodeEntry::kEmptyResourceName,
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
JITLineInfoTable* line_info = NULL, Address instruction_start = NULL);
void AddObserver(CodeEventObserver* observer);
void RemoveObserver(CodeEventObserver* observer);
V8_INLINE bool HasObservers() { return !observers_.empty(); }
const char* GetName(Name* name) {
return function_and_resource_names_.GetName(name);
}
const char* GetName(int args_count) {
return function_and_resource_names_.GetName(args_count);
}
const char* GetFunctionName(Name* name) {
return function_and_resource_names_.GetFunctionName(name);
}
const char* GetFunctionName(const char* name) {
return function_and_resource_names_.GetFunctionName(name);
}
private:
void RecordInliningInfo(CodeEntry* entry, AbstractCode* abstract_code);
void RecordDeoptInlinedFrames(CodeEntry* entry, AbstractCode* abstract_code);
Name* InferScriptName(Name* name, SharedFunctionInfo* info);
V8_INLINE void DispatchCodeEvent(const CodeEventsContainer& evt_rec) {
for (auto observer : observers_) {
observer->CodeEventHandler(evt_rec);
}
}
StringsStorage function_and_resource_names_;
std::vector<CodeEntry*> code_entries_;
std::vector<CodeEventObserver*> observers_;
DISALLOW_COPY_AND_ASSIGN(ProfilerListener);
};
} // namespace internal
} // namespace v8
#endif // V8_PROFILER_PROFILER_LISTENER_H_
......@@ -1002,6 +1002,8 @@
'profiler/heap-snapshot-generator-inl.h',
'profiler/heap-snapshot-generator.cc',
'profiler/heap-snapshot-generator.h',
'profiler/profiler-listener.cc',
'profiler/profiler-listener.h',
'profiler/profile-generator-inl.h',
'profiler/profile-generator.cc',
'profiler/profile-generator.h',
......
......@@ -33,6 +33,7 @@
#include "src/base/platform/platform.h"
#include "src/deoptimizer.h"
#include "src/profiler/cpu-profiler-inl.h"
#include "src/profiler/profiler-listener.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
#include "test/cctest/profiler-extension.h"
......@@ -45,6 +46,7 @@ using i::Heap;
using i::ProfileGenerator;
using i::ProfileNode;
using i::ProfilerEventsProcessor;
using i::ProfilerListener;
using i::ScopedVector;
using i::Vector;
......@@ -158,24 +160,29 @@ TEST(CodeEvents) {
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
ProfilerListener profiler_listener(isolate);
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
profiler_listener.AddObserver(&profiler);
// Enqueue code creation events.
const char* aaa_str = "aaa";
i::Handle<i::String> aaa_name = factory->NewStringFromAsciiChecked(aaa_str);
profiler.CodeCreateEvent(i::CodeEventListener::FUNCTION_TAG, aaa_code,
*aaa_name);
profiler.CodeCreateEvent(i::CodeEventListener::BUILTIN_TAG, comment_code,
"comment");
profiler.CodeCreateEvent(i::CodeEventListener::STUB_TAG, args5_code, 5);
profiler.CodeCreateEvent(i::CodeEventListener::BUILTIN_TAG, comment2_code,
"comment2");
profiler.CodeMoveEvent(comment2_code, moved_code->address());
profiler.CodeCreateEvent(i::CodeEventListener::STUB_TAG, args3_code, 3);
profiler.CodeCreateEvent(i::CodeEventListener::STUB_TAG, args4_code, 4);
profiler_listener.CodeCreateEvent(i::Logger::FUNCTION_TAG, aaa_code,
*aaa_name);
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code,
"comment");
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5);
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code,
"comment2");
profiler_listener.CodeMoveEvent(comment2_code, moved_code->address());
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3);
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4);
// Enqueue a tick event to enable code events processing.
EnqueueTickSampleEvent(processor, aaa_code->address());
profiler_listener.RemoveObserver(&profiler);
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
processor->StopSynchronously();
// Check the state of profile generator.
......@@ -221,12 +228,13 @@ TEST(TickEvents) {
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
ProfilerListener profiler_listener(isolate);
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
profiler_listener.AddObserver(&profiler);
profiler.CodeCreateEvent(i::CodeEventListener::BUILTIN_TAG, frame1_code,
"bbb");
profiler.CodeCreateEvent(i::CodeEventListener::STUB_TAG, frame2_code, 5);
profiler.CodeCreateEvent(i::CodeEventListener::BUILTIN_TAG, frame3_code,
"ddd");
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb");
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5);
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame3_code, "ddd");
EnqueueTickSampleEvent(processor, frame1_code->instruction_start());
EnqueueTickSampleEvent(
......@@ -237,6 +245,8 @@ TEST(TickEvents) {
frame2_code->instruction_end() - 1,
frame1_code->instruction_end() - 1);
profiler_listener.RemoveObserver(&profiler);
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
processor->StopSynchronously();
CpuProfile* profile = profiles->StopProfiling("");
CHECK(profile);
......@@ -257,6 +267,8 @@ TEST(TickEvents) {
const i::List<ProfileNode*>* top_down_ddd_children =
top_down_stub_children->last()->children();
CHECK_EQ(0, top_down_ddd_children->length());
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
}
// http://crbug/51594
......@@ -288,8 +300,11 @@ TEST(Issue1398) {
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
ProfilerListener profiler_listener(isolate);
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
profiler_listener.AddObserver(&profiler);
profiler.CodeCreateEvent(i::CodeEventListener::BUILTIN_TAG, code, "bbb");
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb");
i::TickSample* sample = processor->StartTickSample();
sample->pc = code->address();
......@@ -300,6 +315,8 @@ TEST(Issue1398) {
}
processor->FinishTickSample();
profiler_listener.RemoveObserver(&profiler);
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
processor->StopSynchronously();
CpuProfile* profile = profiles->StopProfiling("");
CHECK(profile);
......@@ -1026,17 +1043,22 @@ static void TickLines(bool optimize) {
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
ProfilerListener profiler_listener(isolate);
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
profiler_listener.AddObserver(&profiler);
// Enqueue code creation events.
i::Handle<i::String> str = factory->NewStringFromAsciiChecked(func_name);
int line = 1;
int column = 1;
profiler.CodeCreateEvent(i::CodeEventListener::FUNCTION_TAG, code,
func->shared(), *str, line, column);
profiler_listener.CodeCreateEvent(i::Logger::FUNCTION_TAG, code,
func->shared(), *str, line, column);
// Enqueue a tick event to enable code events processing.
EnqueueTickSampleEvent(processor, code_address);
profiler_listener.RemoveObserver(&profiler);
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
processor->StopSynchronously();
CpuProfile* profile = profiles->StopProfiling("");
......@@ -1129,8 +1151,8 @@ TEST(FunctionCallSample) {
const v8::CpuProfileNode* start_node = GetChild(env.local(), root, "start");
GetChild(env.local(), start_node, "bar");
const v8::CpuProfileNode* unresolved_node = FindChild(
env.local(), root, i::ProfileGenerator::kUnresolvedFunctionName);
const v8::CpuProfileNode* unresolved_node =
FindChild(env.local(), root, i::CodeEntry::kUnresolvedFunctionName);
CHECK(!unresolved_node || GetChild(env.local(), unresolved_node, "call"));
profile->Delete();
......@@ -1185,8 +1207,8 @@ TEST(FunctionApplySample) {
GetChild(env.local(), start_node, "test");
GetChild(env.local(), test_node, "bar");
const v8::CpuProfileNode* unresolved_node = FindChild(
env.local(), start_node, ProfileGenerator::kUnresolvedFunctionName);
const v8::CpuProfileNode* unresolved_node =
FindChild(env.local(), start_node, CodeEntry::kUnresolvedFunctionName);
CHECK(!unresolved_node || GetChild(env.local(), unresolved_node, "apply"));
profile->Delete();
......@@ -1593,12 +1615,12 @@ TEST(IdleTime) {
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* program_node =
GetChild(env.local(), root, ProfileGenerator::kProgramEntryName);
GetChild(env.local(), root, CodeEntry::kProgramEntryName);
CHECK_EQ(0, program_node->GetChildrenCount());
CHECK_GE(program_node->GetHitCount(), 2u);
const v8::CpuProfileNode* idle_node =
GetChild(env.local(), root, ProfileGenerator::kIdleEntryName);
GetChild(env.local(), root, CodeEntry::kIdleEntryName);
CHECK_EQ(0, idle_node->GetChildrenCount());
CHECK_GE(idle_node->GetHitCount(), 3u);
......
......@@ -348,12 +348,9 @@ TEST(RecordTickSample) {
profiles.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler());
profiles.StartProfiling("", false);
ProfileGenerator generator(&profiles);
CodeEntry* entry1 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "aaa");
CodeEntry* entry2 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "bbb");
CodeEntry* entry3 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "ccc");
CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa");
CodeEntry* entry2 = new CodeEntry(i::Logger::FUNCTION_TAG, "bbb");
CodeEntry* entry3 = new CodeEntry(i::Logger::FUNCTION_TAG, "ccc");
generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
......@@ -401,6 +398,10 @@ TEST(RecordTickSample) {
ProfileNode* node4 = top_down_test_helper.Walk(entry1, entry3, entry1);
CHECK(node4);
CHECK_EQ(entry1, node4->entry());
delete entry1;
delete entry2;
delete entry3;
}
......@@ -418,12 +419,9 @@ TEST(SampleIds) {
profiles.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler());
profiles.StartProfiling("", true);
ProfileGenerator generator(&profiles);
CodeEntry* entry1 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "aaa");
CodeEntry* entry2 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "bbb");
CodeEntry* entry3 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "ccc");
CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa");
CodeEntry* entry2 = new CodeEntry(i::Logger::FUNCTION_TAG, "bbb");
CodeEntry* entry3 = new CodeEntry(i::Logger::FUNCTION_TAG, "ccc");
generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
......@@ -464,6 +462,10 @@ TEST(SampleIds) {
for (int i = 0; i < 3; i++) {
CHECK_EQ(expected_id[i], profile->sample(i)->id());
}
delete entry1;
delete entry2;
delete entry3;
}
......@@ -473,8 +475,7 @@ TEST(NoSamples) {
profiles.set_cpu_profiler(CcTest::i_isolate()->cpu_profiler());
profiles.StartProfiling("", false);
ProfileGenerator generator(&profiles);
CodeEntry* entry1 =
profiles.NewCodeEntry(i::CodeEventListener::FUNCTION_TAG, "aaa");
CodeEntry* entry1 = new CodeEntry(i::Logger::FUNCTION_TAG, "aaa");
generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
// We are building the following calls tree:
......@@ -491,6 +492,8 @@ TEST(NoSamples) {
CHECK_EQ(3u, nodeId - 1);
CHECK_EQ(0, profile->samples_count());
delete entry1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment