profile-generator.h revision 109988c7ccb6f3fd1a58574fa3dfb88beaef6632
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 46ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_PROFILER_PROFILE_GENERATOR_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_PROFILER_PROFILE_GENERATOR_H_ 76ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <map> 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-profiler.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hashmap.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/strings-storage.h" 146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 156ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 { 166ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal { 176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Provides a mapping from the offsets within generated code to 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the source line. 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass JITLineInfoTable : public Malloced { 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable(); 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~JITLineInfoTable(); 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetPosition(int pc_offset, int line); 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int GetSourceLineNumber(int pc_offset) const; 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool empty() const { return pc_offset_map_.empty(); } 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // pc_offset -> source line 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier typedef std::map<int, int> PcOffsetMap; 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PcOffsetMap pc_offset_map_; 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(JITLineInfoTable); 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 386ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeEntry { 396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // CodeEntry doesn't own name strings, just references them. 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline CodeEntry(Logger::LogEventsAndTags tag, const char* name, 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_prefix = CodeEntry::kEmptyNamePrefix, 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* resource_name = CodeEntry::kEmptyResourceName, 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line_number = v8::CpuProfileNode::kNoLineNumberInfo, 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable* line_info = NULL, 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address instruction_start = NULL); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~CodeEntry(); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_prefix() const { return name_prefix_; } 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_name_prefix() const { return name_prefix_[0] != '\0'; } 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name() const { return name_; } 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* resource_name() const { return resource_name_; } 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line_number() const { return line_number_; } 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int column_number() const { return column_number_; } 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const JITLineInfoTable* line_info() const { return line_info_; } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int script_id() const { return script_id_; } 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_script_id(int script_id) { script_id_ = script_id; } 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position() const { return position_; } 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_position(int position) { position_ = position; } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_bailout_reason(const char* bailout_reason) { 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bailout_reason_ = bailout_reason; 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* bailout_reason() const { return bailout_reason_; } 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_deopt_info(const char* deopt_reason, SourcePosition position, 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t pc_offset) { 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(deopt_position_.IsUnknown()); 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deopt_reason_ = deopt_reason; 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deopt_position_ = position; 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_offset_ = pc_offset; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuProfileDeoptInfo GetDeoptInfo(); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* deopt_reason() const { return deopt_reason_; } 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition deopt_position() const { return deopt_position_; } 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_deopt_info() const { return !deopt_position_.IsUnknown(); } 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void clear_deopt_info() { 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deopt_reason_ = kNoDeoptReason; 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deopt_position_ = SourcePosition::Unknown(); 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void FillFunctionInfo(SharedFunctionInfo* shared); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_inlined_function_infos( 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const std::vector<InlinedFunctionInfo>& infos) { 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_function_infos_ = infos; 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const std::vector<InlinedFunctionInfo> inlined_function_infos() { 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return inlined_function_infos_; 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetBuiltinId(Builtins::Name id); 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Builtins::Name builtin_id() const { 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return BuiltinIdField::decode(bit_field_); 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t GetHash() const; 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsSameFunctionAs(CodeEntry* entry) const; 99f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int GetSourceLine(int pc_offset) const; 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address instruction_start() const { return instruction_start_; } 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kEmptyNamePrefix; 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kEmptyResourceName; 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kEmptyBailoutReason; 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const char* const kNoDeoptReason; 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class TagField : public BitField<Logger::LogEventsAndTags, 0, 8> {}; 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class BuiltinIdField : public BitField<Builtins::Name, 8, 8> {}; 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Logger::LogEventsAndTags tag() const { return TagField::decode(bit_field_); } 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bit_field_; 1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_prefix_; 1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_; 1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* resource_name_; 1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_number_; 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int column_number_; 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int script_id_; 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position_; 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* bailout_reason_; 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* deopt_reason_; 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition deopt_position_; 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t pc_offset_; 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable* line_info_; 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address instruction_start_; 1286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::vector<InlinedFunctionInfo> inlined_function_infos_; 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeEntry); 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTree; 1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileNode { 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline ProfileNode(ProfileTree* tree, CodeEntry* entry); 1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* FindChild(CodeEntry* entry); 1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* FindOrAddChild(CodeEntry* entry); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncrementSelfTicks() { ++self_ticks_; } 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; } 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void IncrementLineTicks(int src_line); 1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* entry() const { return entry_; } 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned self_ticks() const { return self_ticks_; } 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const List<ProfileNode*>* children() const { return &children_list_; } 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned id() const { return id_; } 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned function_id() const; 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); } 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GetLineTicks(v8::CpuProfileNode::LineTick* entries, 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned int length) const; 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CollectDeoptInfo(CodeEntry* entry); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const std::vector<CpuProfileDeoptInfo>& deopt_infos() const { 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return deopt_infos_; 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate() const; 1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(int indent); 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool CodeEntriesMatch(void* entry1, void* entry2) { 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<CodeEntry*>(entry1) 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->IsSameFunctionAs(reinterpret_cast<CodeEntry*>(entry2)); 1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t CodeEntryHash(CodeEntry* entry) { return entry->GetHash(); } 1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool LineTickMatch(void* a, void* b) { return a == b; } 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree* tree_; 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry_; 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned self_ticks_; 1763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping from CodeEntry* to ProfileNode* 1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HashMap children_; 1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<ProfileNode*> children_list_; 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned id_; 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HashMap line_ticks_; 1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::vector<CpuProfileDeoptInfo> deopt_infos_; 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileNode); 1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTree { 1896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit ProfileTree(Isolate* isolate); 1916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~ProfileTree(); 1926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ProfileNode* AddPathFromEnd( 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Vector<CodeEntry*>& path, 195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int src_line = v8::CpuProfileNode::kNoLineNumberInfo, 196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool update_stats = true); 1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root() const { return root_; } 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned next_node_id() { return next_node_id_++; } 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned GetFunctionId(const ProfileNode* node); 2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print() { 2026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->Print(0); 2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate() const { return isolate_; } 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block template <typename Callback> 209f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void TraverseDepthFirst(Callback* callback); 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry root_entry_; 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned next_node_id_; 2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root_; 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned next_function_id_; 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HashMap function_ids_; 2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileTree); 2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfile { 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuProfile(Isolate* isolate, const char* title, bool record_samples); 2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Add pc -> ... -> main() call path to the profile. 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddPath(base::TimeTicks timestamp, const Vector<CodeEntry*>& path, 229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int src_line, bool update_stats); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CalculateTotalTicksAndSamplingRate(); 2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* title() const { return title_; } 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ProfileTree* top_down() const { return &top_down_; } 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int samples_count() const { return samples_.length(); } 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProfileNode* sample(int index) const { return samples_.at(index); } 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks sample_timestamp(int index) const { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return timestamps_.at(index); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks start_time() const { return start_time_; } 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks end_time() const { return end_time_; } 2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void UpdateTicksScale(); 2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* title_; 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool record_samples_; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks start_time_; 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks end_time_; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ProfileNode*> samples_; 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<base::TimeTicks> timestamps_; 2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree top_down_; 2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfile); 2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2616ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeMap { 2626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeMap() {} 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~CodeMap(); 265589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void AddCode(Address addr, CodeEntry* entry, unsigned size); 266589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void MoveCode(Address from, Address to); 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeEntry* FindEntry(Address addr); 26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block int GetSharedId(Address addr); 2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeEntryInfo { 2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : entry(an_entry), size(a_size) { } 2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry; 2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned size; 2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeTreeConfig { 2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef Address Key; 2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef CodeEntryInfo Value; 2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const Key kNoKey; 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const Value NoValue() { return CodeEntryInfo(NULL, 0); } 2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static int Compare(const Key& a, const Key& b) { 2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return a < b ? -1 : (a > b ? 1 : 0); 2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef SplayTree<CodeTreeConfig> CodeTree; 2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block class CodeTreePrinter { 2926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Call(const Address& key, const CodeEntryInfo& value); 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 296589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void DeleteAllCoveredCode(Address start, Address end); 297589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeTree tree_; 2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeMap); 3016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfilesCollection { 3056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit CpuProfilesCollection(Heap* heap); 3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~CpuProfilesCollection(); 3086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool StartProfiling(const char* title, bool record_samples); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuProfile* StopProfiling(const char* title); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<CpuProfile*>* profiles() { return &finished_profiles_; } 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetName(Name* name) { 3137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return function_and_resource_names_.GetName(name); 3147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 315f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char* GetName(int args_count) { 316f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return function_and_resource_names_.GetName(args_count); 317f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetFunctionName(Name* name) { 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return function_and_resource_names_.GetFunctionName(name); 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetFunctionName(const char* name) { 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return function_and_resource_names_.GetFunctionName(name); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 324756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bool IsLastProfile(const char* title); 32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveProfile(CpuProfile* profile); 3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* NewCodeEntry( 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Logger::LogEventsAndTags tag, const char* name, 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_prefix = CodeEntry::kEmptyNamePrefix, 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* resource_name = CodeEntry::kEmptyResourceName, 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line_number = v8::CpuProfileNode::kNoLineNumberInfo, 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable* line_info = NULL, Address instruction_start = NULL); 3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Called from profile generator thread. 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddPathToCurrentProfiles(base::TimeTicks timestamp, 337109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Vector<CodeEntry*>& path, int src_line, 338109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool update_stats); 3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Limits the number of profiles that can be simultaneously collected. 34180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaxSimultaneousProfiles = 100; 34280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 3447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch StringsStorage function_and_resource_names_; 3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CodeEntry*> code_entries_; 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<CpuProfile*> finished_profiles_; 3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Accessed by VM thread and profile generator thread. 3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CpuProfile*> current_profiles_; 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Semaphore current_profiles_semaphore_; 3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileGenerator { 3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block explicit ProfileGenerator(CpuProfilesCollection* profiles); 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void RecordTickSample(const TickSample& sample); 3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeMap* code_map() { return &code_map_; } 3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kProgramEntryName; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kIdleEntryName; 36844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kGarbageCollectorEntryName; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Used to represent frames for which we have no reliable way to 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // detect function. 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kUnresolvedFunctionName; 3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* EntryForVMState(StateTag tag); 3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CpuProfilesCollection* profiles_; 3776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeMap code_map_; 3786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* program_entry_; 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* idle_entry_; 3806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* gc_entry_; 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* unresolved_entry_; 3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); 3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_PROFILER_PROFILE_GENERATOR_H_ 391