diff --git a/src/cpu-profiler-inl.h b/src/cpu-profiler-inl.h index 4982197cab..408d46bfb7 100644 --- a/src/cpu-profiler-inl.h +++ b/src/cpu-profiler-inl.h @@ -64,16 +64,6 @@ TickSample* ProfilerEventsProcessor::TickSampleEvent() { } -bool ProfilerEventsProcessor::FilterOutCodeCreateEvent( - Logger::LogEventsAndTags tag) { - return FLAG_prof_browser_mode - && (tag != Logger::CALLBACK_TAG - && tag != Logger::FUNCTION_TAG - && tag != Logger::LAZY_COMPILE_TAG - && tag != Logger::REG_EXP_TAG - && tag != Logger::SCRIPT_TAG); -} - } } // namespace v8::internal #endif // V8_CPU_PROFILER_INL_H_ diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc index 109ddd5d97..bdb4ec427e 100644 --- a/src/cpu-profiler.cc +++ b/src/cpu-profiler.cc @@ -58,120 +58,9 @@ ProfilerEventsProcessor::ProfilerEventsProcessor( } -void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag, - const char* prefix, - Name* name, - Address start) { - if (FilterOutCodeCreateEvent(tag)) return; - CodeEventsContainer evt_rec; - CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; - rec->type = CodeEventRecord::CODE_CREATION; - rec->order = ++enqueue_order_; - rec->start = start; - rec->entry = profiles_->NewCodeEntry(tag, prefix, name); - rec->size = 1; - rec->shared = NULL; - events_buffer_.Enqueue(evt_rec); -} - - -void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, - Name* name, - String* resource_name, - int line_number, - Address start, - unsigned size, - Address shared, - CompilationInfo* info) { - if (FilterOutCodeCreateEvent(tag)) return; - CodeEventsContainer evt_rec; - CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; - rec->type = CodeEventRecord::CODE_CREATION; - rec->order = ++enqueue_order_; - rec->start = start; - rec->entry = profiles_->NewCodeEntry(tag, name, resource_name, line_number); - if (info) { - rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); - } - rec->size = size; - rec->shared = shared; - events_buffer_.Enqueue(evt_rec); -} - - -void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, - const char* name, - Address start, - unsigned size) { - if (FilterOutCodeCreateEvent(tag)) return; - CodeEventsContainer evt_rec; - CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; - rec->type = CodeEventRecord::CODE_CREATION; - rec->order = ++enqueue_order_; - rec->start = start; - rec->entry = profiles_->NewCodeEntry(tag, name); - rec->size = size; - rec->shared = NULL; - events_buffer_.Enqueue(evt_rec); -} - - -void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, - int args_count, - Address start, - unsigned size) { - if (FilterOutCodeCreateEvent(tag)) return; - CodeEventsContainer evt_rec; - CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; - rec->type = CodeEventRecord::CODE_CREATION; - rec->order = ++enqueue_order_; - rec->start = start; - rec->entry = profiles_->NewCodeEntry(tag, args_count); - rec->size = size; - rec->shared = NULL; - events_buffer_.Enqueue(evt_rec); -} - - -void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) { - CodeEventsContainer evt_rec; - CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; - rec->type = CodeEventRecord::CODE_MOVE; - rec->order = ++enqueue_order_; - rec->from = from; - rec->to = to; - events_buffer_.Enqueue(evt_rec); -} - - -void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from, - Address to) { - CodeEventsContainer evt_rec; - SharedFunctionInfoMoveEventRecord* rec = - &evt_rec.SharedFunctionInfoMoveEventRecord_; - rec->type = CodeEventRecord::SHARED_FUNC_MOVE; - rec->order = ++enqueue_order_; - rec->from = from; - rec->to = to; - events_buffer_.Enqueue(evt_rec); -} - - -void ProfilerEventsProcessor::RegExpCodeCreateEvent( - Logger::LogEventsAndTags tag, - const char* prefix, - String* name, - Address start, - unsigned size) { - if (FilterOutCodeCreateEvent(tag)) return; - CodeEventsContainer evt_rec; - CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; - rec->type = CodeEventRecord::CODE_CREATION; - rec->order = ++enqueue_order_; - rec->start = start; - rec->entry = profiles_->NewCodeEntry(tag, prefix, name); - rec->size = size; - events_buffer_.Enqueue(evt_rec); +void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { + event.generic.order = ++enqueue_order_; + events_buffer_.Enqueue(event); } @@ -305,30 +194,56 @@ bool CpuProfiler::HasDetachedProfiles() { } +static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag) { + return FLAG_prof_browser_mode + && (tag != Logger::CALLBACK_TAG + && tag != Logger::FUNCTION_TAG + && tag != Logger::LAZY_COMPILE_TAG + && tag != Logger::REG_EXP_TAG + && tag != Logger::SCRIPT_TAG); +} + + void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { - processor_->CallbackCreateEvent( - Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point); + if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = entry_point; + rec->entry = profiles_->NewCodeEntry( + Logger::CALLBACK_TAG, + profiles_->GetName(name), + TokenEnumerator::kInheritsSecurityToken); + rec->size = 1; + rec->shared = NULL; + processor_->Enqueue(evt_rec); } void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, - Code* code, const char* comment) { - processor_->CodeCreateEvent( - tag, comment, code->address(), code->ExecutableSize()); + Code* code, + const char* name) { + if (FilterOutCodeCreateEvent(tag)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = code->address(); + rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); + rec->size = code->ExecutableSize(); + rec->shared = NULL; + processor_->Enqueue(evt_rec); } void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, - Code* code, Name* name) { - processor_->CodeCreateEvent( - tag, - name, - isolate_->heap()->empty_string(), - v8::CpuProfileNode::kNoLineNumberInfo, - code->address(), - code->ExecutableSize(), - NULL, - NULL); + Code* code, + Name* name) { + if (FilterOutCodeCreateEvent(tag)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = code->address(); + rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); + rec->size = code->ExecutableSize(); + rec->shared = NULL; + processor_->Enqueue(evt_rec); } @@ -337,15 +252,17 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, SharedFunctionInfo* shared, CompilationInfo* info, Name* name) { - processor_->CodeCreateEvent( - tag, - name, - isolate_->heap()->empty_string(), - v8::CpuProfileNode::kNoLineNumberInfo, - code->address(), - code->ExecutableSize(), - shared->address(), - info); + if (FilterOutCodeCreateEvent(tag)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = code->address(); + rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); + rec->entry->set_no_frame_ranges(info ? + info->ReleaseNoFrameRanges() : + NULL); + rec->size = code->ExecutableSize(); + rec->shared = shared->address(); + processor_->Enqueue(evt_rec); } @@ -354,30 +271,50 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, SharedFunctionInfo* shared, CompilationInfo* info, String* source, int line) { - processor_->CodeCreateEvent( + if (FilterOutCodeCreateEvent(tag)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = code->address(); + rec->entry = profiles_->NewCodeEntry( tag, - shared->DebugName(), - source, - line, - code->address(), - code->ExecutableSize(), - shared->address(), - info); + profiles_->GetFunctionName(shared->DebugName()), + TokenEnumerator::kNoSecurityToken, + CodeEntry::kEmptyNamePrefix, + profiles_->GetName(source), + line); + rec->entry->set_no_frame_ranges(info ? + info->ReleaseNoFrameRanges() : + NULL); + rec->size = code->ExecutableSize(); + rec->shared = shared->address(); + processor_->Enqueue(evt_rec); } void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, - Code* code, int args_count) { - processor_->CodeCreateEvent( + Code* code, + int args_count) { + if (FilterOutCodeCreateEvent(tag)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = code->address(); + rec->entry = profiles_->NewCodeEntry( tag, - args_count, - code->address(), - code->ExecutableSize()); + profiles_->GetName(args_count), + TokenEnumerator::kInheritsSecurityToken, + "args_count: "); + rec->size = code->ExecutableSize(); + rec->shared = NULL; + processor_->Enqueue(evt_rec); } void CpuProfiler::CodeMoveEvent(Address from, Address to) { - processor_->CodeMoveEvent(from, to); + CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE); + CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; + rec->from = from; + rec->to = to; + processor_->Enqueue(evt_rec); } @@ -386,29 +323,59 @@ void CpuProfiler::CodeDeleteEvent(Address from) { void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) { - processor_->SharedFunctionInfoMoveEvent(from, to); + CodeEventsContainer evt_rec(CodeEventRecord::SHARED_FUNC_MOVE); + SharedFunctionInfoMoveEventRecord* rec = + &evt_rec.SharedFunctionInfoMoveEventRecord_; + rec->from = from; + rec->to = to; + processor_->Enqueue(evt_rec); } void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { - processor_->CallbackCreateEvent( - Logger::CALLBACK_TAG, "get ", name, entry_point); + if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = entry_point; + rec->entry = profiles_->NewCodeEntry( + Logger::CALLBACK_TAG, + profiles_->GetName(name), + TokenEnumerator::kInheritsSecurityToken, + "get "); + rec->size = 1; + rec->shared = NULL; + processor_->Enqueue(evt_rec); } void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { - processor_->RegExpCodeCreateEvent( + if (FilterOutCodeCreateEvent(Logger::REG_EXP_TAG)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = code->address(); + rec->entry = profiles_->NewCodeEntry( Logger::REG_EXP_TAG, - "RegExp: ", - source, - code->address(), - code->ExecutableSize()); + profiles_->GetName(source), + TokenEnumerator::kInheritsSecurityToken, + "RegExp: "); + rec->size = code->ExecutableSize(); + processor_->Enqueue(evt_rec); } void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { - processor_->CallbackCreateEvent( - Logger::CALLBACK_TAG, "set ", name, entry_point); + if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; + CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); + CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; + rec->start = entry_point; + rec->entry = profiles_->NewCodeEntry( + Logger::CALLBACK_TAG, + profiles_->GetName(name), + TokenEnumerator::kInheritsSecurityToken, + "set "); + rec->size = 1; + rec->shared = NULL; + processor_->Enqueue(evt_rec); } @@ -424,6 +391,21 @@ CpuProfiler::CpuProfiler(Isolate* isolate) } +CpuProfiler::CpuProfiler(Isolate* isolate, + CpuProfilesCollection* test_profiles, + ProfileGenerator* test_generator, + ProfilerEventsProcessor* test_processor) + : isolate_(isolate), + profiles_(test_profiles), + next_profile_uid_(1), + token_enumerator_(new TokenEnumerator()), + generator_(test_generator), + processor_(test_processor), + need_to_stop_sampler_(false), + is_profiling_(false) { +} + + CpuProfiler::~CpuProfiler() { delete token_enumerator_; delete profiles_; diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h index 455c893328..c66f99e17f 100644 --- a/src/cpu-profiler.h +++ b/src/cpu-profiler.h @@ -63,7 +63,7 @@ class CodeEventRecord { #undef DECLARE_TYPE Type type; - unsigned order; + mutable unsigned order; }; @@ -122,6 +122,21 @@ class TickSampleEventRecord { }; +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 Thread { @@ -134,29 +149,8 @@ class ProfilerEventsProcessor : public Thread { virtual void Run(); inline void Stop() { running_ = false; } INLINE(bool running()) { return running_; } + void Enqueue(const CodeEventsContainer& event); - // Events adding methods. Called by VM threads. - void CallbackCreateEvent(Logger::LogEventsAndTags tag, - const char* prefix, Name* name, - Address start); - void CodeCreateEvent(Logger::LogEventsAndTags tag, - Name* name, - String* resource_name, int line_number, - Address start, unsigned size, - Address shared, - CompilationInfo* info); - void CodeCreateEvent(Logger::LogEventsAndTags tag, - const char* name, - Address start, unsigned size); - void CodeCreateEvent(Logger::LogEventsAndTags tag, - int args_count, - Address start, unsigned size); - void CodeMoveEvent(Address from, Address to); - void CodeDeleteEvent(Address from); - void SharedFunctionInfoMoveEvent(Address from, Address to); - void RegExpCodeCreateEvent(Logger::LogEventsAndTags tag, - const char* prefix, String* name, - Address start, unsigned size); // Puts current stack into tick sample events buffer. void AddCurrentStack(); @@ -167,19 +161,10 @@ class ProfilerEventsProcessor : public Thread { INLINE(TickSample* TickSampleEvent()); private: - union CodeEventsContainer { - CodeEventRecord generic; -#define DECLARE_CLASS(ignore, type) type type##_; - CODE_EVENTS_TYPE_LIST(DECLARE_CLASS) -#undef DECLARE_TYPE - }; - // Called from events processing thread (Run() method.) bool ProcessCodeEvent(unsigned* dequeue_order); bool ProcessTicks(unsigned dequeue_order); - INLINE(static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag)); - ProfileGenerator* generator_; CpuProfilesCollection* profiles_; bool running_; @@ -204,6 +189,12 @@ class ProfilerEventsProcessor : public Thread { class CpuProfiler { public: explicit CpuProfiler(Isolate* isolate); + + CpuProfiler(Isolate* isolate, + CpuProfilesCollection* test_collection, + ProfileGenerator* test_generator, + ProfilerEventsProcessor* test_processor); + ~CpuProfiler(); void StartProfiling(const char* title, bool record_samples = false); diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h index 6f9a60171e..f2e6ec6650 100644 --- a/src/profile-generator-inl.h +++ b/src/profile-generator-inl.h @@ -44,9 +44,9 @@ const char* StringsStorage::GetFunctionName(const char* name) { CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, - const char* name_prefix, const char* name, int security_token_id, + const char* name_prefix, const char* resource_name, int line_number) : tag_(tag), diff --git a/src/profile-generator.cc b/src/profile-generator.cc index 8505b5b40d..a7f7a440b4 100644 --- a/src/profile-generator.cc +++ b/src/profile-generator.cc @@ -298,7 +298,7 @@ class DeleteNodesCallback { ProfileTree::ProfileTree() - : root_entry_(Logger::FUNCTION_TAG, "", "(root)"), + : root_entry_(Logger::FUNCTION_TAG, "(root)"), next_node_id_(1), root_(new ProfileNode(this, &root_entry_)) { } @@ -787,54 +787,6 @@ List* CpuProfilesCollection::Profiles(int security_token_id) { } -CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, - Name* name, - String* resource_name, - int line_number) { - CodeEntry* entry = new CodeEntry(tag, - CodeEntry::kEmptyNamePrefix, - GetFunctionName(name), - TokenEnumerator::kNoSecurityToken, - GetName(resource_name), - line_number); - code_entries_.Add(entry); - return entry; -} - - -CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, - const char* name) { - CodeEntry* entry = new CodeEntry(tag, - CodeEntry::kEmptyNamePrefix, - GetFunctionName(name)); - code_entries_.Add(entry); - return entry; -} - - -CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, - const char* name_prefix, - Name* name) { - CodeEntry* entry = new CodeEntry(tag, - name_prefix, - GetName(name), - TokenEnumerator::kInheritsSecurityToken); - code_entries_.Add(entry); - return entry; -} - - -CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, - int args_count) { - CodeEntry* entry = new CodeEntry(tag, - "args_count: ", - GetName(args_count), - TokenEnumerator::kInheritsSecurityToken); - code_entries_.Add(entry); - return entry; -} - - void CpuProfilesCollection::AddPathToCurrentProfiles( const Vector& path) { // As starting / stopping profiles is rare relatively to this @@ -848,6 +800,24 @@ void CpuProfilesCollection::AddPathToCurrentProfiles( } +CodeEntry* CpuProfilesCollection::NewCodeEntry( + Logger::LogEventsAndTags tag, + const char* name, + int security_token_id, + const char* name_prefix, + const char* resource_name, + int line_number) { + CodeEntry* code_entry = new CodeEntry(tag, + name, + security_token_id, + name_prefix, + resource_name, + line_number); + code_entries_.Add(code_entry); + return code_entry; +} + + void SampleRateCalculator::Tick() { if (--wall_time_query_countdown_ == 0) UpdateMeasurements(OS::TimeCurrentMillis()); diff --git a/src/profile-generator.h b/src/profile-generator.h index f8534e4c3f..38451d11b7 100644 --- a/src/profile-generator.h +++ b/src/profile-generator.h @@ -97,9 +97,9 @@ class CodeEntry { public: // CodeEntry doesn't own name strings, just references them. INLINE(CodeEntry(Logger::LogEventsAndTags tag, - const char* name_prefix, const char* name, int security_token_id = TokenEnumerator::kNoSecurityToken, + const char* name_prefix = CodeEntry::kEmptyNamePrefix, const char* resource_name = CodeEntry::kEmptyResourceName, int line_number = v8::CpuProfileNode::kNoLineNumberInfo)); ~CodeEntry(); @@ -318,18 +318,24 @@ class CpuProfilesCollection { 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); + } CpuProfile* GetProfile(int security_token_id, unsigned uid); bool IsLastProfile(const char* title); void RemoveProfile(CpuProfile* profile); bool HasDetachedProfiles() { return detached_profiles_.length() > 0; } - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, - Name* name, String* resource_name, int line_number); - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name); - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, - const char* name_prefix, Name* name); - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count); - CodeEntry* NewCodeEntry(int security_token_id); + CodeEntry* NewCodeEntry( + Logger::LogEventsAndTags tag, + const char* name, + int security_token_id = TokenEnumerator::kNoSecurityToken, + const char* name_prefix = CodeEntry::kEmptyNamePrefix, + const char* resource_name = CodeEntry::kEmptyResourceName, + int line_number = v8::CpuProfileNode::kNoLineNumberInfo); // Called from profile generator thread. void AddPathToCurrentProfiles(const Vector& path); @@ -338,12 +344,6 @@ class CpuProfilesCollection { static const int kMaxSimultaneousProfiles = 100; private: - 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); - } int GetProfileIndex(unsigned uid); List* GetProfilesList(int security_token_id); int TokenToIndex(int security_token_id); diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc index 9a2496a72a..6075fe1606 100644 --- a/test/cctest/test-cpu-profiler.cc +++ b/test/cctest/test-cpu-profiler.cc @@ -97,64 +97,87 @@ class TestSetup { } // namespace + +i::Code* CreateCode(LocalContext* env) { + static int counter = 0; + char script[256]; + char name[32]; + snprintf(name, sizeof(name), "function_%d", ++counter); + snprintf(script, sizeof(script), + "function %s() {\n" + "var counter = 0;\n" + "for (var i = 0; i < %d; ++i) counter += i;\n" + "return '%s_' + counter;\n" + "}\n" + "%s();\n", name, counter, name, name); + CompileRun(script); + i::Handle fun = v8::Utils::OpenHandle( + *v8::Local::Cast((*env)->Global()->Get(v8_str(name)))); + fprintf(stderr, "code size: %d\n", fun->code()->ExecutableSize()); + return fun->code(); +} + + TEST(CodeEvents) { CcTest::InitializeVM(); + LocalContext env; i::Isolate* isolate = i::Isolate::Current(); - i::Heap* heap = isolate->heap(); i::Factory* factory = isolate->factory(); TestSetup test_setup; - CpuProfilesCollection profiles; - profiles.StartProfiling("", 1, false); - ProfileGenerator generator(&profiles); - ProfilerEventsProcessor processor(&generator, &profiles); + + i::HandleScope scope(isolate); + + i::Code* aaa_code = CreateCode(&env); + i::Code* comment_code = CreateCode(&env); + i::Code* args5_code = CreateCode(&env); + i::Code* comment2_code = CreateCode(&env); + i::Code* moved_code = CreateCode(&env); + i::Code* args3_code = CreateCode(&env); + i::Code* args4_code = CreateCode(&env); + + CpuProfilesCollection* profiles = new CpuProfilesCollection; + profiles->StartProfiling("", 1, false); + ProfileGenerator generator(profiles); + ProfilerEventsProcessor processor(&generator, profiles); processor.Start(); + CpuProfiler profiler(isolate, profiles, &generator, &processor); // Enqueue code creation events. - i::HandleScope scope(isolate); const char* aaa_str = "aaa"; i::Handle aaa_name = factory->NewStringFromAscii( i::Vector(aaa_str, i::StrLength(aaa_str))); - processor.CodeCreateEvent(i::Logger::FUNCTION_TAG, - *aaa_name, - heap->empty_string(), - 0, - ToAddress(0x1000), - 0x100, - ToAddress(0x10000), - NULL); - processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, - "bbb", - ToAddress(0x1200), - 0x80); - processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); - processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, - "ddd", - ToAddress(0x1400), - 0x80); - processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500)); - processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10); - processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10); + profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, aaa_code, *aaa_name); + profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code, "comment"); + profiler.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5); + profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code, "comment2"); + profiler.CodeMoveEvent(comment2_code->address(), moved_code->address()); + profiler.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3); + profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4); + // Enqueue a tick event to enable code events processing. - EnqueueTickSampleEvent(&processor, ToAddress(0x1000)); + EnqueueTickSampleEvent(&processor, aaa_code->address()); processor.Stop(); processor.Join(); // Check the state of profile generator. - CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000)); - CHECK_NE(NULL, entry1); - CHECK_EQ(aaa_str, entry1->name()); - CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200)); - CHECK_NE(NULL, entry2); - CHECK_EQ("bbb", entry2->name()); - CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300)); - CHECK_NE(NULL, entry3); - CHECK_EQ("5", entry3->name()); - CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400))); - CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500)); - CHECK_NE(NULL, entry4); - CHECK_EQ("ddd", entry4->name()); - CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600))); + CodeEntry* aaa = generator.code_map()->FindEntry(aaa_code->address()); + CHECK_NE(NULL, aaa); + CHECK_EQ(aaa_str, aaa->name()); + + CodeEntry* comment = generator.code_map()->FindEntry(comment_code->address()); + CHECK_NE(NULL, comment); + CHECK_EQ("comment", comment->name()); + + CodeEntry* args5 = generator.code_map()->FindEntry(args5_code->address()); + CHECK_NE(NULL, args5); + CHECK_EQ("5", args5->name()); + + CHECK_EQ(NULL, generator.code_map()->FindEntry(comment2_code->address())); + + CodeEntry* comment2 = generator.code_map()->FindEntry(moved_code->address()); + CHECK_NE(NULL, comment2); + CHECK_EQ("comment2", comment2->name()); } @@ -165,32 +188,40 @@ static int CompareProfileNodes(const T* p1, const T* p2) { TEST(TickEvents) { TestSetup test_setup; - CpuProfilesCollection profiles; - profiles.StartProfiling("", 1, false); - ProfileGenerator generator(&profiles); - ProfilerEventsProcessor processor(&generator, &profiles); - processor.Start(); + LocalContext env; + i::Isolate* isolate = i::Isolate::Current(); + i::HandleScope scope(isolate); - processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, - "bbb", - ToAddress(0x1200), - 0x80); - processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); - processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, - "ddd", - ToAddress(0x1400), - 0x80); - EnqueueTickSampleEvent(&processor, ToAddress(0x1210)); - EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220)); - EnqueueTickSampleEvent(&processor, - ToAddress(0x1404), - ToAddress(0x1305), - ToAddress(0x1230)); + i::Code* frame1_code = CreateCode(&env); + i::Code* frame2_code = CreateCode(&env); + i::Code* frame3_code = CreateCode(&env); + + CpuProfilesCollection* profiles = new CpuProfilesCollection; + profiles->StartProfiling("", 1, false); + ProfileGenerator generator(profiles); + ProfilerEventsProcessor processor(&generator, profiles); + processor.Start(); + CpuProfiler profiler(isolate, profiles, &generator, &processor); + + profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb"); + profiler.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5); + profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame3_code, "ddd"); + + EnqueueTickSampleEvent(&processor, frame1_code->instruction_start()); + EnqueueTickSampleEvent( + &processor, + frame2_code->instruction_start() + frame2_code->ExecutableSize() / 2, + frame1_code->instruction_start() + frame2_code->ExecutableSize() / 2); + EnqueueTickSampleEvent( + &processor, + frame3_code->instruction_end() - 1, + frame2_code->instruction_end() - 1, + frame1_code->instruction_end() - 1); processor.Stop(); processor.Join(); CpuProfile* profile = - profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); + profiles->StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); CHECK_NE(NULL, profile); // Check call trees. @@ -229,29 +260,33 @@ TEST(CrashIfStoppingLastNonExistentProfile) { // Long stacks (exceeding max frames limit) must not be erased. TEST(Issue1398) { TestSetup test_setup; - CpuProfilesCollection profiles; - profiles.StartProfiling("", 1, false); - ProfileGenerator generator(&profiles); - ProfilerEventsProcessor processor(&generator, &profiles); - processor.Start(); + LocalContext env; + i::Isolate* isolate = i::Isolate::Current(); + i::HandleScope scope(isolate); - processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, - "bbb", - ToAddress(0x1200), - 0x80); + i::Code* code = CreateCode(&env); + + CpuProfilesCollection* profiles = new CpuProfilesCollection; + profiles->StartProfiling("", 1, false); + ProfileGenerator generator(profiles); + ProfilerEventsProcessor processor(&generator, profiles); + processor.Start(); + CpuProfiler profiler(isolate, profiles, &generator, &processor); + + profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb"); i::TickSample* sample = processor.TickSampleEvent(); - sample->pc = ToAddress(0x1200); + sample->pc = code->address(); sample->tos = 0; sample->frames_count = i::TickSample::kMaxFramesCount; for (int i = 0; i < sample->frames_count; ++i) { - sample->stack[i] = ToAddress(0x1200); + sample->stack[i] = code->address(); } processor.Stop(); processor.Join(); CpuProfile* profile = - profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); + profiles->StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); CHECK_NE(NULL, profile); int actual_depth = 0; diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc index 17c9dd9f01..e919789673 100644 --- a/test/cctest/test-profile-generator.cc +++ b/test/cctest/test-profile-generator.cc @@ -87,17 +87,17 @@ TEST(TokenEnumerator) { TEST(ProfileNodeFindOrAddChild) { ProfileTree tree; ProfileNode node(&tree, NULL); - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); ProfileNode* childNode1 = node.FindOrAddChild(&entry1); CHECK_NE(NULL, childNode1); CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); ProfileNode* childNode2 = node.FindOrAddChild(&entry2); CHECK_NE(NULL, childNode2); CHECK_NE(childNode1, childNode2); CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); ProfileNode* childNode3 = node.FindOrAddChild(&entry3); CHECK_NE(NULL, childNode3); CHECK_NE(childNode1, childNode3); @@ -109,19 +109,18 @@ TEST(ProfileNodeFindOrAddChild) { TEST(ProfileNodeFindOrAddChildForSameFunction) { - const char* empty = ""; const char* aaa = "aaa"; ProfileTree tree; ProfileNode node(&tree, NULL); - CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa); + CodeEntry entry1(i::Logger::FUNCTION_TAG, aaa); ProfileNode* childNode1 = node.FindOrAddChild(&entry1); CHECK_NE(NULL, childNode1); CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); // The same function again. - CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa); + CodeEntry entry2(i::Logger::FUNCTION_TAG, aaa); CHECK_EQ(childNode1, node.FindOrAddChild(&entry2)); // Now with a different security token. - CodeEntry entry3(i::Logger::FUNCTION_TAG, empty, aaa, + CodeEntry entry3(i::Logger::FUNCTION_TAG, aaa, TokenEnumerator::kNoSecurityToken + 1); CHECK_EQ(childNode1, node.FindOrAddChild(&entry3)); } @@ -157,9 +156,9 @@ class ProfileTreeTestHelper { } // namespace TEST(ProfileTreeAddPathFromStart) { - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); ProfileTree tree; ProfileTreeTestHelper helper(&tree); CHECK_EQ(NULL, helper.Walk(&entry1)); @@ -224,9 +223,9 @@ TEST(ProfileTreeAddPathFromStart) { TEST(ProfileTreeAddPathFromEnd) { - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); ProfileTree tree; ProfileTreeTestHelper helper(&tree); CHECK_EQ(NULL, helper.Walk(&entry1)); @@ -304,7 +303,7 @@ TEST(ProfileTreeCalculateTotalTicks) { CHECK_EQ(1, empty_tree.root()->total_ticks()); CHECK_EQ(1, empty_tree.root()->self_ticks()); - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry* e1_path[] = {&entry1}; Vector e1_path_vec( e1_path, sizeof(e1_path) / sizeof(e1_path[0])); @@ -325,7 +324,7 @@ TEST(ProfileTreeCalculateTotalTicks) { CHECK_EQ(1, node1->total_ticks()); CHECK_EQ(1, node1->self_ticks()); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); CodeEntry* e1_e2_path[] = {&entry1, &entry2}; Vector e1_e2_path_vec( e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0])); @@ -360,7 +359,7 @@ TEST(ProfileTreeCalculateTotalTicks) { CodeEntry* e2_path[] = {&entry2}; Vector e2_path_vec( e2_path, sizeof(e2_path) / sizeof(e2_path[0])); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); CodeEntry* e3_path[] = {&entry3}; Vector e3_path_vec( e3_path, sizeof(e3_path) / sizeof(e3_path[0])); @@ -418,10 +417,10 @@ TEST(ProfileTreeCalculateTotalTicks) { TEST(ProfileTreeFilteredClone) { ProfileTree source_tree; const int token0 = 0, token1 = 1, token2 = 2; - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", token0); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", token1); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", token0); - CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd", + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", token0); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", token1); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc", token0); + CodeEntry entry4(i::Logger::FUNCTION_TAG, "ddd", TokenEnumerator::kInheritsSecurityToken); { @@ -519,10 +518,10 @@ static inline i::Address ToAddress(int n) { TEST(CodeMapAddCode) { CodeMap code_map; - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); - CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd"); + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); + CodeEntry entry4(i::Logger::FUNCTION_TAG, "ddd"); code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); code_map.AddCode(ToAddress(0x1900), &entry3, 0x50); @@ -549,8 +548,8 @@ TEST(CodeMapAddCode) { TEST(CodeMapMoveAndDeleteCode) { CodeMap code_map; - CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); - CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); + CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); + CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); @@ -558,7 +557,7 @@ TEST(CodeMapMoveAndDeleteCode) { code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb. CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500))); CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700))); - CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); code_map.AddCode(ToAddress(0x1750), &entry3, 0x100); CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700))); CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));