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, 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int src_line = v8::CpuProfileNode::kNoLineNumberInfo); 1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root() const { return root_; } 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned next_node_id() { return next_node_id_++; } 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned GetFunctionId(const ProfileNode* node); 1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print() { 2016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->Print(0); 2026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate() const { return isolate_; } 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block template <typename Callback> 208f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void TraverseDepthFirst(Callback* callback); 2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry root_entry_; 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned next_node_id_; 2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root_; 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned next_function_id_; 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HashMap function_ids_; 2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileTree); 2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfile { 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuProfile(Isolate* isolate, const char* title, bool record_samples); 2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Add pc -> ... -> main() call path to the profile. 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddPath(base::TimeTicks timestamp, const Vector<CodeEntry*>& path, 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int src_line); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CalculateTotalTicksAndSamplingRate(); 2306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* title() const { return title_; } 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ProfileTree* top_down() const { return &top_down_; } 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int samples_count() const { return samples_.length(); } 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProfileNode* sample(int index) const { return samples_.at(index); } 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks sample_timestamp(int index) const { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return timestamps_.at(index); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks start_time() const { return start_time_; } 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks end_time() const { return end_time_; } 2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void UpdateTicksScale(); 2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* title_; 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool record_samples_; 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks start_time_; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks end_time_; 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ProfileNode*> samples_; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<base::TimeTicks> timestamps_; 2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree top_down_; 2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfile); 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeMap { 2616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeMap() {} 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~CodeMap(); 264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void AddCode(Address addr, CodeEntry* entry, unsigned size); 265589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void MoveCode(Address from, Address to); 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeEntry* FindEntry(Address addr); 26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int GetSharedId(Address addr); 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeEntryInfo { 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) 2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : entry(an_entry), size(a_size) { } 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry; 2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned size; 2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeTreeConfig { 2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef Address Key; 2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef CodeEntryInfo Value; 2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const Key kNoKey; 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const Value NoValue() { return CodeEntryInfo(NULL, 0); } 2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static int Compare(const Key& a, const Key& b) { 2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return a < b ? -1 : (a > b ? 1 : 0); 2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef SplayTree<CodeTreeConfig> CodeTree; 2896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block class CodeTreePrinter { 2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 2926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Call(const Address& key, const CodeEntryInfo& value); 2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 295589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void DeleteAllCoveredCode(Address start, Address end); 296589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeTree tree_; 2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeMap); 3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfilesCollection { 3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit CpuProfilesCollection(Heap* heap); 3066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~CpuProfilesCollection(); 3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool StartProfiling(const char* title, bool record_samples); 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuProfile* StopProfiling(const char* title); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<CpuProfile*>* profiles() { return &finished_profiles_; } 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetName(Name* name) { 3127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return function_and_resource_names_.GetName(name); 3137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 314f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char* GetName(int args_count) { 315f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return function_and_resource_names_.GetName(args_count); 316f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetFunctionName(Name* name) { 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return function_and_resource_names_.GetFunctionName(name); 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetFunctionName(const char* name) { 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return function_and_resource_names_.GetFunctionName(name); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 323756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bool IsLastProfile(const char* title); 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveProfile(CpuProfile* profile); 3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* NewCodeEntry( 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Logger::LogEventsAndTags tag, const char* name, 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_prefix = CodeEntry::kEmptyNamePrefix, 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* resource_name = CodeEntry::kEmptyResourceName, 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line_number = v8::CpuProfileNode::kNoLineNumberInfo, 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable* line_info = NULL, Address instruction_start = NULL); 3336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Called from profile generator thread. 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddPathToCurrentProfiles(base::TimeTicks timestamp, 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Vector<CodeEntry*>& path, int src_line); 3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 33880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Limits the number of profiles that can be simultaneously collected. 33980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaxSimultaneousProfiles = 100; 34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 3427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch StringsStorage function_and_resource_names_; 3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CodeEntry*> code_entries_; 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<CpuProfile*> finished_profiles_; 3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Accessed by VM thread and profile generator thread. 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CpuProfile*> current_profiles_; 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Semaphore current_profiles_semaphore_; 3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); 3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileGenerator { 3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block explicit ProfileGenerator(CpuProfilesCollection* profiles); 3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void RecordTickSample(const TickSample& sample); 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeMap* code_map() { return &code_map_; } 3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kProgramEntryName; 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kIdleEntryName; 36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kGarbageCollectorEntryName; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Used to represent frames for which we have no reliable way to 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // detect function. 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kUnresolvedFunctionName; 3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* EntryForVMState(StateTag tag); 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CpuProfilesCollection* profiles_; 3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeMap code_map_; 3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* program_entry_; 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* idle_entry_; 3786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* gc_entry_; 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* unresolved_entry_; 3806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); 3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_PROFILER_PROFILE_GENERATOR_H_ 389