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 "src/allocation.h" 1013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/hashmap.h" 11f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/log.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/strings-storage.h" 13f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/source-position.h" 146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 156ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 { 166ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal { 176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct TickSample; 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Provides a mapping from the offsets within generated code to 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the source line. 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass JITLineInfoTable : public Malloced { 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable(); 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~JITLineInfoTable(); 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetPosition(int pc_offset, int line); 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int GetSourceLineNumber(int pc_offset) const; 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool empty() const { return pc_offset_map_.empty(); } 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // pc_offset -> source line 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier typedef std::map<int, int> PcOffsetMap; 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PcOffsetMap pc_offset_map_; 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(JITLineInfoTable); 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 406ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeEntry { 416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // CodeEntry doesn't own name strings, just references them. 4313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch inline CodeEntry(CodeEventListener::LogEventsAndTags tag, const char* name, 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_prefix = CodeEntry::kEmptyNamePrefix, 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* resource_name = CodeEntry::kEmptyResourceName, 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line_number = v8::CpuProfileNode::kNoLineNumberInfo, 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int column_number = v8::CpuProfileNode::kNoColumnNumberInfo, 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable* line_info = NULL, 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address instruction_start = NULL); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~CodeEntry(); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_prefix() const { return name_prefix_; } 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_name_prefix() const { return name_prefix_[0] != '\0'; } 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name() const { return name_; } 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* resource_name() const { return resource_name_; } 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line_number() const { return line_number_; } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int column_number() const { return column_number_; } 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const JITLineInfoTable* line_info() const { return line_info_; } 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int script_id() const { return script_id_; } 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_script_id(int script_id) { script_id_ = script_id; } 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position() const { return position_; } 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_position(int position) { position_ = position; } 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_bailout_reason(const char* bailout_reason) { 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bailout_reason_ = bailout_reason; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* bailout_reason() const { return bailout_reason_; } 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void set_deopt_info(const char* deopt_reason, int deopt_id) { 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!has_deopt_info()); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deopt_reason_ = deopt_reason; 71bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch deopt_id_ = deopt_id; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuProfileDeoptInfo GetDeoptInfo(); 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool has_deopt_info() const { return deopt_id_ != kNoDeoptimizationId; } 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void clear_deopt_info() { 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch deopt_reason_ = kNoDeoptReason; 77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch deopt_id_ = kNoDeoptimizationId; 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void FillFunctionInfo(SharedFunctionInfo* shared); 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetBuiltinId(Builtins::Name id); 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Builtins::Name builtin_id() const { 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return BuiltinIdField::decode(bit_field_); 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t GetHash() const; 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsSameFunctionAs(CodeEntry* entry) const; 89f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int GetSourceLine(int pc_offset) const; 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 92c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void AddInlineStack(int pc_offset, std::vector<CodeEntry*> inline_stack); 933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const std::vector<CodeEntry*>* GetInlineStack(int pc_offset) const; 943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 95c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void AddDeoptInlinedFrames(int deopt_id, std::vector<CpuProfileDeoptFrame>); 96bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool HasDeoptInlinedFramesFor(int deopt_id) const; 97bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address instruction_start() const { return instruction_start_; } 9913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CodeEventListener::LogEventsAndTags tag() const { 10013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return TagField::decode(bit_field_); 10113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kEmptyNamePrefix; 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kEmptyResourceName; 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kEmptyBailoutReason; 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const char* const kNoDeoptReason; 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 10813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static const char* const kProgramEntryName; 10913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static const char* const kIdleEntryName; 11013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static const char* const kGarbageCollectorEntryName; 11113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Used to represent frames for which we have no reliable way to 11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // detect function. 11313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static const char* const kUnresolvedFunctionName; 11413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V8_INLINE static CodeEntry* program_entry() { 11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return kProgramEntry.Pointer(); 11713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 11813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V8_INLINE static CodeEntry* idle_entry() { return kIdleEntry.Pointer(); } 11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V8_INLINE static CodeEntry* gc_entry() { return kGCEntry.Pointer(); } 12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch V8_INLINE static CodeEntry* unresolved_entry() { 12113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return kUnresolvedEntry.Pointer(); 12213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct ProgramEntryCreateTrait { 12613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static CodeEntry* Create(); 12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch }; 12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct IdleEntryCreateTrait { 12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static CodeEntry* Create(); 13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch }; 13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct GCEntryCreateTrait { 13213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static CodeEntry* Create(); 13313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch }; 13413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct UnresolvedEntryCreateTrait { 13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static CodeEntry* Create(); 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch }; 13713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::LazyDynamicInstance<CodeEntry, ProgramEntryCreateTrait>::type 13913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch kProgramEntry; 14013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::LazyDynamicInstance<CodeEntry, IdleEntryCreateTrait>::type 14113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch kIdleEntry; 14213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::LazyDynamicInstance<CodeEntry, GCEntryCreateTrait>::type 14313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch kGCEntry; 14413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::LazyDynamicInstance<CodeEntry, UnresolvedEntryCreateTrait>::type 14513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch kUnresolvedEntry; 14613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class TagField : public BitField<Logger::LogEventsAndTags, 0, 8> {}; 14813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch class BuiltinIdField : public BitField<Builtins::Name, 8, 24> {}; 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bit_field_; 1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_prefix_; 1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_; 1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* resource_name_; 1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_number_; 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int column_number_; 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int script_id_; 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position_; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* bailout_reason_; 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* deopt_reason_; 160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int deopt_id_; 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JITLineInfoTable* line_info_; 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address instruction_start_; 1633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Should be an unordered_map, but it doesn't currently work on Win & MacOS. 1643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch std::map<int, std::vector<CodeEntry*>> inline_locations_; 165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::map<int, std::vector<CpuProfileDeoptFrame>> deopt_inlined_frames_; 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeEntry); 1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTree; 1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileNode { 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch inline ProfileNode(ProfileTree* tree, CodeEntry* entry, ProfileNode* parent); 1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* FindChild(CodeEntry* entry); 1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* FindOrAddChild(CodeEntry* entry); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncrementSelfTicks() { ++self_ticks_; } 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; } 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void IncrementLineTicks(int src_line); 1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* entry() const { return entry_; } 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned self_ticks() const { return self_ticks_; } 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const List<ProfileNode*>* children() const { return &children_list_; } 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned id() const { return id_; } 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned function_id() const; 188c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ProfileNode* parent() const { return parent_; } 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); } 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool GetLineTicks(v8::CpuProfileNode::LineTick* entries, 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned int length) const; 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CollectDeoptInfo(CodeEntry* entry); 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const std::vector<CpuProfileDeoptInfo>& deopt_infos() const { 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return deopt_infos_; 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate() const; 1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(int indent); 1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool CodeEntriesMatch(void* entry1, void* entry2) { 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<CodeEntry*>(entry1) 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->IsSameFunctionAs(reinterpret_cast<CodeEntry*>(entry2)); 2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t CodeEntryHash(CodeEntry* entry) { return entry->GetHash(); } 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static bool LineTickMatch(void* a, void* b) { return a == b; } 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree* tree_; 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry_; 2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned self_ticks_; 2133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping from CodeEntry* to ProfileNode* 214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch base::CustomMatcherHashMap children_; 2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<ProfileNode*> children_list_; 216c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ProfileNode* parent_; 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned id_; 218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch base::CustomMatcherHashMap line_ticks_; 2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::vector<CpuProfileDeoptInfo> deopt_infos_; 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileNode); 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTree { 2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit ProfileTree(Isolate* isolate); 2296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~ProfileTree(); 2306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ProfileNode* AddPathFromEnd( 2323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const std::vector<CodeEntry*>& path, 233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int src_line = v8::CpuProfileNode::kNoLineNumberInfo, 234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool update_stats = true); 2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root() const { return root_; } 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned next_node_id() { return next_node_id_++; } 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned GetFunctionId(const ProfileNode* node); 2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print() { 2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->Print(0); 2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate() const { return isolate_; } 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void EnqueueNode(const ProfileNode* node) { pending_nodes_.push_back(node); } 246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch size_t pending_nodes_count() const { return pending_nodes_.size(); } 247c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::vector<const ProfileNode*> TakePendingNodes() { 248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return std::move(pending_nodes_); 249c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 250c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 2516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block template <typename Callback> 253f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void TraverseDepthFirst(Callback* callback); 2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::vector<const ProfileNode*> pending_nodes_; 256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry root_entry_; 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned next_node_id_; 2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root_; 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned next_function_id_; 263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch base::CustomMatcherHashMap function_ids_; 2646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileTree); 2666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfile { 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CpuProfile(CpuProfiler* profiler, const char* title, bool record_samples); 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Add pc -> ... -> main() call path to the profile. 2743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void AddPath(base::TimeTicks timestamp, const std::vector<CodeEntry*>& path, 275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int src_line, bool update_stats); 276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void FinishProfile(); 2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* title() const { return title_; } 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ProfileTree* top_down() const { return &top_down_; } 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int samples_count() const { return samples_.length(); } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProfileNode* sample(int index) const { return samples_.at(index); } 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks sample_timestamp(int index) const { 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return timestamps_.at(index); 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks start_time() const { return start_time_; } 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks end_time() const { return end_time_; } 28913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CpuProfiler* cpu_profiler() const { return profiler_; } 2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void UpdateTicksScale(); 2926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void StreamPendingTraceEvents(); 297c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* title_; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool record_samples_; 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks start_time_; 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeTicks end_time_; 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<ProfileNode*> samples_; 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<base::TimeTicks> timestamps_; 3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree top_down_; 30513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CpuProfiler* const profiler_; 306c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int streaming_next_sample_; 3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfile); 3096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3116ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeMap { 3126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeMap() {} 31413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 315589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void AddCode(Address addr, CodeEntry* entry, unsigned size); 316589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void MoveCode(Address from, Address to); 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeEntry* FindEntry(Address addr); 3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 3216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeEntryInfo { 3226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) 3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : entry(an_entry), size(a_size) { } 3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry; 3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned size; 3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 3276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 328589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void DeleteAllCoveredCode(Address start, Address end); 329589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 33013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch std::map<Address, CodeEntryInfo> code_map_; 3316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeMap); 3336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3356ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfilesCollection { 3366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 33713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch explicit CpuProfilesCollection(Isolate* isolate); 3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~CpuProfilesCollection(); 3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 34013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void set_cpu_profiler(CpuProfiler* profiler) { profiler_ = profiler; } 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool StartProfiling(const char* title, bool record_samples); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CpuProfile* StopProfiling(const char* title); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<CpuProfile*>* profiles() { return &finished_profiles_; } 34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const char* GetName(Name* name) { return resource_names_.GetName(name); } 345756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bool IsLastProfile(const char* title); 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveProfile(CpuProfile* profile); 3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Called from profile generator thread. 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void AddPathToCurrentProfiles(base::TimeTicks timestamp, 3503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const std::vector<CodeEntry*>& path, 3513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int src_line, bool update_stats); 3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 35380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Limits the number of profiles that can be simultaneously collected. 35480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaxSimultaneousProfiles = 100; 35580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 35713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch StringsStorage resource_names_; 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<CpuProfile*> finished_profiles_; 35913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CpuProfiler* profiler_; 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Accessed by VM thread and profile generator thread. 3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CpuProfile*> current_profiles_; 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Semaphore current_profiles_semaphore_; 3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); 3666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileGenerator { 3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit ProfileGenerator(CpuProfilesCollection* profiles); 3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void RecordTickSample(const TickSample& sample); 3746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeMap* code_map() { return &code_map_; } 3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 378c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CodeEntry* FindEntry(void* address); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeEntry* EntryForVMState(StateTag tag); 3806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CpuProfilesCollection* profiles_; 3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeMap code_map_; 3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); 3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_PROFILER_PROFILE_GENERATOR_H_ 392