From 344d836d0f973642b833494356b519b7d6361fe2 Mon Sep 17 00:00:00 2001 From: "yurys@chromium.org" Date: Thu, 10 Oct 2013 13:15:47 +0000 Subject: [PATCH] Add column getter to CpuProfileNode CpuProfileNode currently exposes only line number which is not enough for the cases when there is more than one function on the same line. This change exposes column number on CpuProfileNode. BUG=302537 R=jkummerow@chromium.org, loislo@chromium.org Review URL: https://codereview.chromium.org/25541003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17142 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8-profiler.h | 7 ++++++ src/api.cc | 6 +++++ src/cpu-profiler.cc | 5 ++-- src/cpu-profiler.h | 2 +- src/log.cc | 7 +++--- src/log.h | 4 +-- src/profile-generator-inl.h | 4 ++- src/profile-generator.cc | 6 +++-- src/profile-generator.h | 9 +++++-- test/cctest/test-cpu-profiler.cc | 53 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 90 insertions(+), 13 deletions(-) diff --git a/include/v8-profiler.h b/include/v8-profiler.h index c393039..7016a79 100644 --- a/include/v8-profiler.h +++ b/include/v8-profiler.h @@ -57,6 +57,12 @@ class V8_EXPORT CpuProfileNode { */ int GetLineNumber() const; + /** + * Returns 1-based number of the column where the function originates. + * kNoColumnNumberInfo if no column number information is available. + */ + int GetColumnNumber() const; + /** Returns bailout reason for the function * if the optimization was disabled for it. */ @@ -80,6 +86,7 @@ class V8_EXPORT CpuProfileNode { const CpuProfileNode* GetChild(int index) const; static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; + static const int kNoColumnNumberInfo = Message::kNoColumnInfo; }; diff --git a/src/api.cc b/src/api.cc index 11eaf92..32a3db6 100644 --- a/src/api.cc +++ b/src/api.cc @@ -6928,6 +6928,12 @@ int CpuProfileNode::GetLineNumber() const { } +int CpuProfileNode::GetColumnNumber() const { + return reinterpret_cast(this)-> + entry()->column_number(); +} + + const char* CpuProfileNode::GetBailoutReason() const { const i::ProfileNode* node = reinterpret_cast(this); return node->entry()->bailout_reason(); diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc index 94677c1..b1af621 100644 --- a/src/cpu-profiler.cc +++ b/src/cpu-profiler.cc @@ -261,7 +261,7 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, SharedFunctionInfo* shared, CompilationInfo* info, - Name* source, int line) { + Name* source, int line, int column) { if (FilterOutCodeCreateEvent(tag)) return; CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; @@ -271,7 +271,8 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, profiles_->GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix, profiles_->GetName(source), - line); + line, + column); if (info) { rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); } diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h index 8aba542..fcb9a67 100644 --- a/src/cpu-profiler.h +++ b/src/cpu-profiler.h @@ -238,7 +238,7 @@ class CpuProfiler : public CodeEventListener { Code* code, SharedFunctionInfo* shared, CompilationInfo* info, - Name* source, int line); + Name* source, int line, int column); virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, int args_count); virtual void CodeMovingGCEvent() {} diff --git a/src/log.cc b/src/log.cc index 0f36bfb..b353f54 100644 --- a/src/log.cc +++ b/src/log.cc @@ -212,7 +212,7 @@ void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, SharedFunctionInfo* shared, CompilationInfo* info, - Name* source, int line) { + Name* source, int line, int column) { name_buffer_->Init(tag); name_buffer_->AppendBytes(ComputeMarker(code)); name_buffer_->AppendString(shared->DebugName()); @@ -1232,10 +1232,11 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, SharedFunctionInfo* shared, CompilationInfo* info, Name* source, int line, int column) { - PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line)); + PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column)); if (!is_logging_code_events()) return; - CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line)); + CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line, + column)); if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); diff --git a/src/log.h b/src/log.h index d61c985..c0efd65 100644 --- a/src/log.h +++ b/src/log.h @@ -471,7 +471,7 @@ class CodeEventListener { SharedFunctionInfo* shared, CompilationInfo* info, Name* source, - int line) = 0; + int line, int column) = 0; virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, int args_count) = 0; @@ -510,7 +510,7 @@ class CodeEventLogger : public CodeEventListener { SharedFunctionInfo* shared, CompilationInfo* info, Name* source, - int line); + int line, int column); virtual void RegExpCodeCreateEvent(Code* code, String* source); virtual void CallbackEvent(Name* name, Address entry_point) { } diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h index f2feb73..76a9fb1 100644 --- a/src/profile-generator-inl.h +++ b/src/profile-generator-inl.h @@ -47,13 +47,15 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, const char* name, const char* name_prefix, const char* resource_name, - int line_number) + int line_number, + int column_number) : tag_(tag), builtin_id_(Builtins::builtin_count), name_prefix_(name_prefix), name_(name), resource_name_(resource_name), line_number_(line_number), + column_number_(column_number), shared_id_(0), script_id_(v8::Script::kNoScriptId), no_frame_ranges_(NULL), diff --git a/src/profile-generator.cc b/src/profile-generator.cc index 38c1f78..d8e8c12 100644 --- a/src/profile-generator.cc +++ b/src/profile-generator.cc @@ -546,12 +546,14 @@ CodeEntry* CpuProfilesCollection::NewCodeEntry( const char* name, const char* name_prefix, const char* resource_name, - int line_number) { + int line_number, + int column_number) { CodeEntry* code_entry = new CodeEntry(tag, name, name_prefix, resource_name, - line_number); + line_number, + column_number); code_entries_.Add(code_entry); return code_entry; } diff --git a/src/profile-generator.h b/src/profile-generator.h index 0a4502c..b9536ab 100644 --- a/src/profile-generator.h +++ b/src/profile-generator.h @@ -77,7 +77,9 @@ class CodeEntry { const char* name, const char* name_prefix = CodeEntry::kEmptyNamePrefix, const char* resource_name = CodeEntry::kEmptyResourceName, - int line_number = v8::CpuProfileNode::kNoLineNumberInfo)); + int line_number = v8::CpuProfileNode::kNoLineNumberInfo, + int column_number = + v8::CpuProfileNode::kNoColumnNumberInfo)); ~CodeEntry(); INLINE(bool is_js_function() const) { return is_js_function_tag(tag_); } @@ -86,6 +88,7 @@ class CodeEntry { INLINE(const char* name() const) { return name_; } INLINE(const char* resource_name() const) { return resource_name_; } INLINE(int line_number() const) { return line_number_; } + int column_number() const { return column_number_; } INLINE(void set_shared_id(int shared_id)) { shared_id_ = shared_id; } INLINE(int script_id() const) { return script_id_; } INLINE(void set_script_id(int script_id)) { script_id_ = script_id; } @@ -119,6 +122,7 @@ class CodeEntry { const char* name_; const char* resource_name_; int line_number_; + int column_number_; int shared_id_; int script_id_; List* no_frame_ranges_; @@ -304,7 +308,8 @@ class CpuProfilesCollection { const char* name, const char* name_prefix = CodeEntry::kEmptyNamePrefix, const char* resource_name = CodeEntry::kEmptyResourceName, - int line_number = v8::CpuProfileNode::kNoLineNumberInfo); + int line_number = v8::CpuProfileNode::kNoLineNumberInfo, + int column_number = v8::CpuProfileNode::kNoColumnNumberInfo); // Called from profile generator thread. void AddPathToCurrentProfiles(const Vector& path); diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc index 8ec9605..db645e3 100644 --- a/test/cctest/test-cpu-profiler.cc +++ b/test/cctest/test-cpu-profiler.cc @@ -1389,3 +1389,56 @@ TEST(IdleTime) { cpu_profiler->DeleteAllCpuProfiles(); } + + +static void CheckFunctionDetails(const v8::CpuProfileNode* node, + const char* name, const char* script_name, int script_id, + int line, int column) { + CHECK_EQ(v8::String::New(name), node->GetFunctionName()); + CHECK_EQ(v8::String::New(script_name), node->GetScriptResourceName()); + CHECK_EQ(script_id, node->GetScriptId()); + CHECK_EQ(line, node->GetLineNumber()); + CHECK_EQ(column, node->GetColumnNumber()); +} + + +TEST(FunctionDetails) { + const char* extensions[] = { "v8/profiler" }; + v8::ExtensionConfiguration config(1, extensions); + LocalContext env(&config); + v8::HandleScope handleScope(env->GetIsolate()); + + v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler(); + CHECK_EQ(0, profiler->GetProfileCount()); + v8::Handle script_a = v8::Script::Compile(v8::String::New( + " function foo\n() { try { bar(); } catch(e) {} }\n" + " function bar() { startProfiling(); }\n"), v8::String::New("script_a")); + script_a->Run(); + v8::Handle script_b = v8::Script::Compile(v8::String::New( + "\n\n function baz() { try { foo(); } catch(e) {} }\n" + "\n\nbaz();\n" + "stopProfiling();\n"), v8::String::New("script_b")); + script_b->Run(); + CHECK_EQ(1, profiler->GetProfileCount()); + const v8::CpuProfile* profile = profiler->GetCpuProfile(0); + const v8::CpuProfileNode* current = profile->GetTopDownRoot(); + reinterpret_cast( + const_cast(current))->Print(0); + // The tree should look like this: + // 0 (root) 0 #1 + // 0 (anonymous function) 19 #2 no reason script_b:1 + // 0 baz 19 #3 TryCatchStatement script_b:3 + // 0 foo 18 #4 TryCatchStatement script_a:2 + // 1 bar 18 #5 no reason script_a:3 + const v8::CpuProfileNode* root = profile->GetTopDownRoot(); + const v8::CpuProfileNode* script = GetChild(root, + ProfileGenerator::kAnonymousFunctionName); + CheckFunctionDetails(script, ProfileGenerator::kAnonymousFunctionName, + "script_b", script_b->GetId(), 1, 1); + const v8::CpuProfileNode* baz = GetChild(script, "baz"); + CheckFunctionDetails(baz, "baz", "script_b", script_b->GetId(), 3, 16); + const v8::CpuProfileNode* foo = GetChild(baz, "foo"); + CheckFunctionDetails(foo, "foo", "script_a", script_a->GetId(), 2, 1); + const v8::CpuProfileNode* bar = GetChild(foo, "bar"); + CheckFunctionDetails(bar, "bar", "script_a", script_a->GetId(), 3, 14); +} -- 2.7.4