From 08c40baa1fbf14890109d28d8db14fa64979ba8d Mon Sep 17 00:00:00 2001 From: "yurys@chromium.org" Date: Thu, 2 Oct 2014 11:58:21 +0000 Subject: [PATCH] Revert of Extend CPU profiler with mapping ticks to source lines (patchset #3 id:40001 of https://codereview.chromium.org/616963005/) Reason for revert: It broke layout test fast/events/window-onerror-02.html, error column reported by window.onerror is now wrong (I believe it is because of the change in full-codegen): http://build.chromium.org/p/client.v8/builders/V8-Blink%20Linux%2064%20%28dbg%29/builds/652 Original issue's description: > Extend CPU profiler with mapping ticks to source lines > > The idea behind of this solution is to use the existing "relocation info" instead of consumption the CodeLinePosition events emitted by the V8 compilers. > During generation code and relocation info are generated simultaneously. > When code generation is done you each code object has associated "relocation info". > Relocation information lets V8 to mark interesting places in the generated code: the pointers that might need to be relocated (after garbage collection), > correspondences between the machine program counter and source locations for stack walking. > > This patch: > 1. Add more source positions info in reloc info to make it suitable for source level mapping. > The amount of data should not be increased dramatically because (1) V8 already marks interesting places in the generated code and > (2) V8 does not write redundant information (it writes a pair (pc_offset, pos) only if pos is changed and skips other). > I measured it on Octane benchmark - for unoptimized code the number of source positions may achieve 2x ('lin_solve' from NavierStokes benchmark). > > 2. When a sample happens, CPU profiler finds a code object by pc, then use its reloc info to match the sample to a source line. > If a source line is found that hit counter is increased by one for this line. > > 3. Add a new public V8 API to get the hit source lines by CDT CPU profiler. > Note that it's expected a minor patch in Blink to pack the source level info in JSON to be shown. > > 4.Add a test that checks how the samples are distributed through source lines. > It tests two cases: (1) relocation info created during code generation and (2) relocation info associated with precompiled function's version. > > Patch from Denis Pravdin > BUG=None > LOG=Y > R=svenpanne@chromium.org > > Committed: https://code.google.com/p/v8/source/detail?r=24389 TBR=svenpanne@chromium.org,danno@chromium.org,alph@chromium.org,denis.pravdin@intel.com,weiliang.lin@intel.com BUG=None LOG=N Review URL: https://codereview.chromium.org/624443005 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24394 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8-profiler.h | 20 ------ src/api.cc | 13 ---- src/cpu-profiler.cc | 46 ++++--------- src/full-codegen.cc | 1 - src/profile-generator-inl.h | 21 +++--- src/profile-generator.cc | 143 +++++++-------------------------------- src/profile-generator.h | 59 +++------------- test/cctest/test-cpu-profiler.cc | 98 --------------------------- 8 files changed, 55 insertions(+), 346 deletions(-) diff --git a/include/v8-profiler.h b/include/v8-profiler.h index d021520..7fc193d 100644 --- a/include/v8-profiler.h +++ b/include/v8-profiler.h @@ -22,14 +22,6 @@ typedef uint32_t SnapshotObjectId; */ class V8_EXPORT CpuProfileNode { public: - struct LineTick { - /** The 1-based number of the source line where the function originates. */ - int line; - - /** The count of samples associated with the source line. */ - unsigned int hit_count; - }; - /** Returns function name (empty string for anonymous functions.) */ Handle GetFunctionName() const; @@ -51,18 +43,6 @@ class V8_EXPORT CpuProfileNode { */ int GetColumnNumber() const; - /** - * Returns the number of the function's source lines that collect the samples. - */ - unsigned int GetHitLineCount() const; - - /** Returns the set of source lines that collect the samples. - * The caller allocates buffer and responsible for releasing it. - * True if all available entries are copied, otherwise false. - * The function copies nothing if buffer is not large enough. - */ - bool GetLineTicks(LineTick* entries, unsigned int length) const; - /** Returns bailout reason for the function * if the optimization was disabled for it. */ diff --git a/src/api.cc b/src/api.cc index 883d8c5..512eaeb 100644 --- a/src/api.cc +++ b/src/api.cc @@ -7114,19 +7114,6 @@ int CpuProfileNode::GetColumnNumber() const { } -unsigned int CpuProfileNode::GetHitLineCount() const { - const i::ProfileNode* node = reinterpret_cast(this); - return node->GetHitLineCount(); -} - - -bool CpuProfileNode::GetLineTicks(LineTick* entries, - unsigned int length) const { - const i::ProfileNode* node = reinterpret_cast(this); - return node->GetLineTicks(entries, length); -} - - 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 2cb855a..68a565c 100644 --- a/src/cpu-profiler.cc +++ b/src/cpu-profiler.cc @@ -201,10 +201,7 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 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, - CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, - CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); + rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); rec->size = code->ExecutableSize(); rec->shared = NULL; processor_->Enqueue(evt_rec); @@ -218,10 +215,7 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 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, - CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, - CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); + rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); rec->size = code->ExecutableSize(); rec->shared = NULL; processor_->Enqueue(evt_rec); @@ -237,9 +231,7 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, rec->start = code->address(); rec->entry = profiles_->NewCodeEntry( tag, profiles_->GetFunctionName(shared->DebugName()), - CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), - CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, - NULL, code->instruction_start()); + CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name)); if (info) { rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); } @@ -264,29 +256,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->start = code->address(); - Script* script = Script::cast(shared->script()); - JITLineInfoTable* line_table = NULL; - if (script) { - line_table = new JITLineInfoTable(); - for (RelocIterator it(code); !it.done(); it.next()) { - RelocInfo::Mode mode = it.rinfo()->rmode(); - if (RelocInfo::IsPosition(mode)) { - int position = static_cast(it.rinfo()->data()); - if (position >= 0) { - int pc_offset = static_cast(it.rinfo()->pc() - code->address()); - int line_number = script->GetLineNumber(position) + 1; - line_table->SetPosition(pc_offset, line_number); - } - } - } - } rec->entry = profiles_->NewCodeEntry( tag, profiles_->GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line, - column, line_table, code->instruction_start()); + column); if (info) { rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); } + DCHECK(Script::cast(shared->script())); + Script* script = Script::cast(shared->script()); rec->entry->set_script_id(script->id()->value()); rec->size = code->ExecutableSize(); rec->shared = shared->address(); @@ -304,9 +282,9 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 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()); + tag, + profiles_->GetName(args_count), + "args_count: "); rec->size = code->ExecutableSize(); rec->shared = NULL; processor_->Enqueue(evt_rec); @@ -366,9 +344,9 @@ void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->start = code->address(); rec->entry = profiles_->NewCodeEntry( - Logger::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ", - CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, - CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); + Logger::REG_EXP_TAG, + profiles_->GetName(source), + "RegExp: "); rec->size = code->ExecutableSize(); processor_->Enqueue(evt_rec); } diff --git a/src/full-codegen.cc b/src/full-codegen.cc index edb43ef..35d51d9 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -866,7 +866,6 @@ void FullCodeGenerator::SetExpressionPosition(Expression* expr) { void FullCodeGenerator::SetSourcePosition(int pos) { if (pos != RelocInfo::kNoPosition) { masm_->positions_recorder()->RecordPosition(pos); - masm_->positions_recorder()->WriteRecordedPositions(); } } diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h index c3ffb26..58c124f 100644 --- a/src/profile-generator-inl.h +++ b/src/profile-generator-inl.h @@ -10,10 +10,12 @@ namespace v8 { namespace internal { -CodeEntry::CodeEntry(Logger::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::CodeEntry(Logger::LogEventsAndTags tag, + const char* name, + const char* name_prefix, + const char* resource_name, + int line_number, + int column_number) : tag_(tag), builtin_id_(Builtins::builtin_count), name_prefix_(name_prefix), @@ -24,9 +26,7 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, const char* name, shared_id_(0), script_id_(v8::UnboundScript::kNoScriptId), no_frame_ranges_(NULL), - bailout_reason_(kEmptyBailoutReason), - line_info_(line_info), - instruction_start_(instruction_start) {} + bailout_reason_(kEmptyBailoutReason) { } bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) { @@ -39,16 +39,13 @@ bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) { } -static bool LineTickMatch(void* a, void* b) { return a == b; } - - ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry) : tree_(tree), entry_(entry), self_ticks_(0), children_(CodeEntriesMatch), - id_(tree->next_node_id()), - line_ticks_(LineTickMatch) {} + id_(tree->next_node_id()) { } + } } // namespace v8::internal #endif // V8_PROFILE_GENERATOR_INL_H_ diff --git a/src/profile-generator.cc b/src/profile-generator.cc index 4609c02..6017f12 100644 --- a/src/profile-generator.cc +++ b/src/profile-generator.cc @@ -132,30 +132,6 @@ HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) { } -JITLineInfoTable::JITLineInfoTable() {} - - -JITLineInfoTable::~JITLineInfoTable() {} - - -void JITLineInfoTable::SetPosition(int pc_offset, int line) { - DCHECK(pc_offset >= 0); - DCHECK(line > 0); // The 1-based number of the source line. - if (GetSourceLineNumber(pc_offset) != line) { - pc_offset_map_.insert(std::make_pair(pc_offset, line)); - } -} - -int JITLineInfoTable::GetSourceLineNumber(int pc_offset) const { - PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset); - if (it == pc_offset_map_.end()) { - if (pc_offset_map_.empty()) return v8::CpuProfileNode::kNoLineNumberInfo; - return (--pc_offset_map_.end())->second; - } - return it->second; -} - - const char* const CodeEntry::kEmptyNamePrefix = ""; const char* const CodeEntry::kEmptyResourceName = ""; const char* const CodeEntry::kEmptyBailoutReason = ""; @@ -163,7 +139,6 @@ const char* const CodeEntry::kEmptyBailoutReason = ""; CodeEntry::~CodeEntry() { delete no_frame_ranges_; - delete line_info_; } @@ -206,14 +181,6 @@ void CodeEntry::SetBuiltinId(Builtins::Name id) { } -int CodeEntry::GetSourceLine(int pc_offset) const { - if (line_info_ && !line_info_->empty()) { - return line_info_->GetSourceLineNumber(pc_offset); - } - return v8::CpuProfileNode::kNoLineNumberInfo; -} - - ProfileNode* ProfileNode::FindChild(CodeEntry* entry) { HashMap::Entry* map_entry = children_.Lookup(entry, CodeEntryHash(entry), false); @@ -235,40 +202,6 @@ ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) { } -void ProfileNode::IncrementLineTicks(int src_line) { - if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) return; - // Increment a hit counter of a certain source line. - // Add a new source line if not found. - HashMap::Entry* e = - line_ticks_.Lookup(reinterpret_cast(src_line), src_line, true); - DCHECK(e); - e->value = reinterpret_cast(reinterpret_cast(e->value) + 1); -} - - -bool ProfileNode::GetLineTicks(v8::CpuProfileNode::LineTick* entries, - unsigned int length) const { - if (entries == NULL || length == 0) return false; - - unsigned line_count = line_ticks_.occupancy(); - - if (line_count == 0) return true; - if (length < line_count) return false; - - v8::CpuProfileNode::LineTick* entry = entries; - - for (HashMap::Entry* p = line_ticks_.Start(); p != NULL; - p = line_ticks_.Next(p), entry++) { - entry->line = - static_cast(reinterpret_cast(p->key)); - entry->hit_count = - static_cast(reinterpret_cast(p->value)); - } - - return true; -} - - void ProfileNode::Print(int indent) { base::OS::Print("%5u %*s %s%s %d #%d %s", self_ticks_, indent, "", entry_->name_prefix(), entry_->name(), entry_->script_id(), @@ -309,8 +242,7 @@ ProfileTree::~ProfileTree() { } -ProfileNode* ProfileTree::AddPathFromEnd(const Vector& path, - int src_line) { +ProfileNode* ProfileTree::AddPathFromEnd(const Vector& path) { ProfileNode* node = root_; for (CodeEntry** entry = path.start() + path.length() - 1; entry != path.start() - 1; @@ -320,15 +252,11 @@ ProfileNode* ProfileTree::AddPathFromEnd(const Vector& path, } } node->IncrementSelfTicks(); - if (src_line != v8::CpuProfileNode::kNoLineNumberInfo) { - node->IncrementLineTicks(src_line); - } return node; } -void ProfileTree::AddPathFromStart(const Vector& path, - int src_line) { +void ProfileTree::AddPathFromStart(const Vector& path) { ProfileNode* node = root_; for (CodeEntry** entry = path.start(); entry != path.start() + path.length(); @@ -338,9 +266,6 @@ void ProfileTree::AddPathFromStart(const Vector& path, } } node->IncrementSelfTicks(); - if (src_line != v8::CpuProfileNode::kNoLineNumberInfo) { - node->IncrementLineTicks(src_line); - } } @@ -402,8 +327,8 @@ CpuProfile::CpuProfile(const char* title, bool record_samples) void CpuProfile::AddPath(base::TimeTicks timestamp, - const Vector& path, int src_line) { - ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path, src_line); + const Vector& path) { + ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path); if (record_samples_) { timestamps_.Add(timestamp); samples_.Add(top_frame_node); @@ -592,25 +517,31 @@ void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) { void CpuProfilesCollection::AddPathToCurrentProfiles( - base::TimeTicks timestamp, const Vector& path, int src_line) { + base::TimeTicks timestamp, const Vector& path) { // As starting / stopping profiles is rare relatively to this // method, we don't bother minimizing the duration of lock holding, // e.g. copying contents of the list to a local vector. current_profiles_semaphore_.Wait(); for (int i = 0; i < current_profiles_.length(); ++i) { - current_profiles_[i]->AddPath(timestamp, path, src_line); + current_profiles_[i]->AddPath(timestamp, path); } current_profiles_semaphore_.Signal(); } CodeEntry* CpuProfilesCollection::NewCodeEntry( - Logger::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); + Logger::LogEventsAndTags tag, + const char* name, + const char* name_prefix, + const char* resource_name, + int line_number, + int column_number) { + CodeEntry* code_entry = new CodeEntry(tag, + name, + name_prefix, + resource_name, + line_number, + column_number); code_entries_.Add(code_entry); return code_entry; } @@ -648,15 +579,6 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { // entries vector with NULL values. CodeEntry** entry = entries.start(); memset(entry, 0, entries.length() * sizeof(*entry)); - - // The ProfileNode knows nothing about all versions of generated code for - // the same JS function. The line number information associated with - // the latest version of generated code is used to find a source line number - // for a JS function. Then, the detected source line is passed to - // ProfileNode to increase the tick count for this source line. - int src_line = v8::CpuProfileNode::kNoLineNumberInfo; - bool src_line_not_found = true; - if (sample.pc != NULL) { if (sample.has_external_callback && sample.state == EXTERNAL && sample.top_frame_type == StackFrame::EXIT) { @@ -673,9 +595,10 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { // frame. Check for this case and just skip such samples. if (pc_entry) { List* ranges = pc_entry->no_frame_ranges(); - int pc_offset = - static_cast(sample.pc - pc_entry->instruction_start()); if (ranges) { + Code* code = Code::cast(HeapObject::FromAddress(start)); + int pc_offset = static_cast( + sample.pc - code->instruction_start()); for (int i = 0; i < ranges->length(); i++) { OffsetRange& range = ranges->at(i); if (range.from <= pc_offset && pc_offset < range.to) { @@ -683,11 +606,6 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { } } } - src_line = pc_entry->GetSourceLine(pc_offset); - if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) { - src_line = pc_entry->line_number(); - } - src_line_not_found = false; *entry++ = pc_entry; if (pc_entry->builtin_id() == Builtins::kFunctionCall || @@ -708,22 +626,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { *stack_end = stack_pos + sample.frames_count; stack_pos != stack_end; ++stack_pos) { - Address start = NULL; - *entry = code_map_.FindEntry(*stack_pos, &start); - - // Skip unresolved frames (e.g. internal frame) and get source line of - // the first JS caller. - if (src_line_not_found && *entry) { - int pc_offset = - static_cast(*stack_pos - (*entry)->instruction_start()); - src_line = (*entry)->GetSourceLine(pc_offset); - if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) { - src_line = (*entry)->line_number(); - } - src_line_not_found = false; - } - - entry++; + *entry++ = code_map_.FindEntry(*stack_pos); } } @@ -741,7 +644,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) { } } - profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line); + profiles_->AddPathToCurrentProfiles(sample.timestamp, entries); } diff --git a/src/profile-generator.h b/src/profile-generator.h index 9135fe6..5ebb92b 100644 --- a/src/profile-generator.h +++ b/src/profile-generator.h @@ -5,7 +5,6 @@ #ifndef V8_PROFILE_GENERATOR_H_ #define V8_PROFILE_GENERATOR_H_ -#include #include "include/v8-profiler.h" #include "src/allocation.h" #include "src/hashmap.h" @@ -45,35 +44,15 @@ class StringsStorage { }; -// Provides a mapping from the offsets within generated code to -// the source line. -class JITLineInfoTable : public Malloced { - public: - JITLineInfoTable(); - ~JITLineInfoTable(); - - void SetPosition(int pc_offset, int line); - int GetSourceLineNumber(int pc_offset) const; - - bool empty() const { return pc_offset_map_.empty(); } - - private: - // pc_offset -> source line - typedef std::map PcOffsetMap; - PcOffsetMap pc_offset_map_; - DISALLOW_COPY_AND_ASSIGN(JITLineInfoTable); -}; - class CodeEntry { public: // CodeEntry doesn't own name strings, just references them. - inline CodeEntry(Logger::LogEventsAndTags tag, const char* name, + inline CodeEntry(Logger::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); + int column_number = v8::CpuProfileNode::kNoColumnNumberInfo); ~CodeEntry(); bool is_js_function() const { return is_js_function_tag(tag_); } @@ -83,7 +62,6 @@ class CodeEntry { const char* resource_name() const { return resource_name_; } int line_number() const { return line_number_; } int column_number() const { return column_number_; } - const JITLineInfoTable* line_info() const { return line_info_; } void set_shared_id(int shared_id) { shared_id_ = shared_id; } int script_id() const { return script_id_; } void set_script_id(int script_id) { script_id_ = script_id; } @@ -105,10 +83,6 @@ class CodeEntry { uint32_t GetCallUid() const; bool IsSameAs(CodeEntry* entry) const; - int GetSourceLine(int pc_offset) const; - - Address instruction_start() const { return instruction_start_; } - static const char* const kEmptyNamePrefix; static const char* const kEmptyResourceName; static const char* const kEmptyBailoutReason; @@ -125,8 +99,6 @@ class CodeEntry { int script_id_; List* no_frame_ranges_; const char* bailout_reason_; - JITLineInfoTable* line_info_; - Address instruction_start_; DISALLOW_COPY_AND_ASSIGN(CodeEntry); }; @@ -142,15 +114,11 @@ class ProfileNode { ProfileNode* FindOrAddChild(CodeEntry* entry); void IncrementSelfTicks() { ++self_ticks_; } void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; } - void IncrementLineTicks(int src_line); CodeEntry* entry() const { return entry_; } unsigned self_ticks() const { return self_ticks_; } const List* children() const { return &children_list_; } unsigned id() const { return id_; } - unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); } - bool GetLineTicks(v8::CpuProfileNode::LineTick* entries, - unsigned int length) const; void Print(int indent); @@ -171,7 +139,6 @@ class ProfileNode { HashMap children_; List children_list_; unsigned id_; - HashMap line_ticks_; DISALLOW_COPY_AND_ASSIGN(ProfileNode); }; @@ -182,11 +149,8 @@ class ProfileTree { ProfileTree(); ~ProfileTree(); - ProfileNode* AddPathFromEnd( - const Vector& path, - int src_line = v8::CpuProfileNode::kNoLineNumberInfo); - void AddPathFromStart(const Vector& path, - int src_line = v8::CpuProfileNode::kNoLineNumberInfo); + ProfileNode* AddPathFromEnd(const Vector& path); + void AddPathFromStart(const Vector& path); ProfileNode* root() const { return root_; } unsigned next_node_id() { return next_node_id_++; } @@ -211,8 +175,7 @@ class CpuProfile { CpuProfile(const char* title, bool record_samples); // Add pc -> ... -> main() call path to the profile. - void AddPath(base::TimeTicks timestamp, const Vector& path, - int src_line); + void AddPath(base::TimeTicks timestamp, const Vector& path); void CalculateTotalTicksAndSamplingRate(); const char* title() const { return title_; } @@ -314,16 +277,16 @@ class CpuProfilesCollection { void RemoveProfile(CpuProfile* profile); CodeEntry* NewCodeEntry( - Logger::LogEventsAndTags tag, const char* name, + Logger::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); + int column_number = v8::CpuProfileNode::kNoColumnNumberInfo); // Called from profile generator thread. - void AddPathToCurrentProfiles(base::TimeTicks timestamp, - const Vector& path, int src_line); + void AddPathToCurrentProfiles( + base::TimeTicks timestamp, const Vector& path); // Limits the number of profiles that can be simultaneously collected. static const int kMaxSimultaneousProfiles = 100; diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc index 72edc27..8d429d2 100644 --- a/test/cctest/test-cpu-profiler.cc +++ b/test/cctest/test-cpu-profiler.cc @@ -1064,104 +1064,6 @@ TEST(BoundFunctionCall) { } -// This tests checks distribution of the samples through the source lines. -TEST(TickLines) { - CcTest::InitializeVM(); - LocalContext env; - i::FLAG_turbo_source_positions = true; - i::Isolate* isolate = CcTest::i_isolate(); - i::Factory* factory = isolate->factory(); - i::HandleScope scope(isolate); - - i::EmbeddedVector script; - - const char* func_name = "func"; - i::SNPrintF(script, - "function %s() {\n" - " var n = 0;\n" - " var m = 100*100;\n" - " while (m > 1) {\n" - " m--;\n" - " n += m * m * m;\n" - " }\n" - "}\n" - "%s();\n", - func_name, func_name); - - CompileRun(script.start()); - - i::Handle func = v8::Utils::OpenHandle( - *v8::Local::Cast((*env)->Global()->Get(v8_str(func_name)))); - CHECK_NE(NULL, func->shared()); - CHECK_NE(NULL, func->shared()->code()); - i::Code* code = NULL; - if (func->code()->is_optimized_code()) { - code = func->code(); - } else { - CHECK(func->shared()->code() == func->code() || !i::FLAG_crankshaft); - code = func->shared()->code(); - } - CHECK_NE(NULL, code); - i::Address code_address = code->instruction_start(); - CHECK_NE(NULL, code_address); - - CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap()); - profiles->StartProfiling("", false); - ProfileGenerator generator(profiles); - SmartPointer processor(new ProfilerEventsProcessor( - &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100))); - processor->Start(); - CpuProfiler profiler(isolate, profiles, &generator, processor.get()); - - // Enqueue code creation events. - i::Handle str = factory->NewStringFromAsciiChecked(func_name); - int line = 1; - int column = 1; - profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, code, func->shared(), NULL, - *str, line, column); - - // Enqueue a tick event to enable code events processing. - EnqueueTickSampleEvent(processor.get(), code_address); - - processor->StopSynchronously(); - - CpuProfile* profile = profiles->StopProfiling(""); - CHECK_NE(NULL, profile); - - // Check the state of profile generator. - CodeEntry* func_entry = generator.code_map()->FindEntry(code_address); - CHECK_NE(NULL, func_entry); - CHECK_EQ(func_name, func_entry->name()); - const i::JITLineInfoTable* line_info = func_entry->line_info(); - CHECK_NE(NULL, line_info); - CHECK(!line_info->empty()); - - // Check the hit source lines using V8 Public APIs. - const i::ProfileTree* tree = profile->top_down(); - ProfileNode* root = tree->root(); - CHECK_NE(NULL, root); - ProfileNode* func_node = root->FindChild(func_entry); - CHECK_NE(NULL, func_node); - - // Add 10 faked ticks to source line #5. - int hit_line = 5; - int hit_count = 10; - for (int i = 0; i < hit_count; i++) func_node->IncrementLineTicks(hit_line); - - unsigned int line_count = func_node->GetHitLineCount(); - CHECK_EQ(2, line_count); // Expect two hit source lines - #1 and #5. - ScopedVector entries(line_count); - CHECK(func_node->GetLineTicks(&entries[0], line_count)); - int value = 0; - for (int i = 0; i < entries.length(); i++) - if (entries[i].line == hit_line) { - value = entries[i].hit_count; - break; - } - CHECK_EQ(hit_count, value); -} - - static const char* call_function_test_source = "function bar(iterations) {\n" "}\n" "function start(duration) {\n" -- 2.7.4