13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 26ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Redistribution and use in source and binary forms, with or without 36ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// modification, are permitted provided that the following conditions are 46ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// met: 56ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// 66ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// * Redistributions of source code must retain the above copyright 76ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// notice, this list of conditions and the following disclaimer. 86ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// * Redistributions in binary form must reproduce the above 96ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// copyright notice, this list of conditions and the following 106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// disclaimer in the documentation and/or other materials provided 116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// with the distribution. 126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// * Neither the name of Google Inc. nor the names of its 136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// contributors may be used to endorse or promote products derived 146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// from this software without specific prior written permission. 156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// 166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_PROFILE_GENERATOR_H_ 296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define V8_PROFILE_GENERATOR_H_ 306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "hashmap.h" 337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#include "../include/v8-profiler.h" 346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 356ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 { 366ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal { 376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtypedef uint32_t SnapshotObjectId; 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeclass TokenEnumerator { 41f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke public: 42f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke TokenEnumerator(); 43f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke ~TokenEnumerator(); 44f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int GetTokenId(Object* token); 45f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static const int kNoSecurityToken = -1; 477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static const int kInheritsSecurityToken = -2; 487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 49f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke private: 50f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static void TokenRemovedCallback(v8::Persistent<v8::Value> handle, 51f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void* parameter); 52f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void TokenRemoved(Object** token_location); 53f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 54f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke List<Object**> token_locations_; 55f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke List<bool> token_removed_; 56f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 57f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke friend class TokenEnumeratorTester; 587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(TokenEnumerator); 607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// Provides a storage of strings allocated in C++ heap, to hold them 647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// forever, even if they disappear from JS heap or external storage. 657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass StringsStorage { 667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch StringsStorage(); 687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ~StringsStorage(); 697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* GetCopy(const char* src); 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* GetFormatted(const char* format, ...); 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* GetVFormatted(const char* format, va_list args); 737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* GetName(String* name); 74f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char* GetName(int index); 75791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block inline const char* GetFunctionName(String* name); 76791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block inline const char* GetFunctionName(const char* name); 777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private: 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kMaxNameSize = 1024; 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch INLINE(static bool StringsMatch(void* key1, void* key2)) { 827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return strcmp(reinterpret_cast<char*>(key1), 837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch reinterpret_cast<char*>(key2)) == 0; 847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* AddOrDisposeString(char* str, uint32_t hash); 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 873bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping of strings by String::Hash to const char* strings. 887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HashMap names_; 897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(StringsStorage); 91f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}; 92f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 93f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 946ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeEntry { 956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // CodeEntry doesn't own name strings, just references them. 976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry(Logger::LogEventsAndTags tag, 986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_prefix, 996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name, 1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* resource_name, 101f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int line_number, 102f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int security_token_id)); 1036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(bool is_js_function() const) { return is_js_function_tag(tag_); } 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const char* name_prefix() const) { return name_prefix_; } 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(bool has_name_prefix() const) { return name_prefix_[0] != '\0'; } 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const char* name() const) { return name_; } 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const char* resource_name() const) { return resource_name_; } 1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(int line_number() const) { return line_number_; } 110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch INLINE(int shared_id() const) { return shared_id_; } 111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch INLINE(void set_shared_id(int shared_id)) { shared_id_ = shared_id; } 112f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke INLINE(int security_token_id() const) { return security_token_id_; } 1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag)); 1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 116f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void CopyData(const CodeEntry& source); 1170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen uint32_t GetCallUid() const; 1180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsSameAs(CodeEntry* entry) const; 119f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kEmptyNamePrefix; 1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Logger::LogEventsAndTags tag_; 1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_prefix_; 1256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_; 1266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* resource_name_; 1276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_number_; 128e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int shared_id_; 129f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int security_token_id_; 1306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeEntry); 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTree; 1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileNode { 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(ProfileNode(ProfileTree* tree, CodeEntry* entry)); 1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* FindChild(CodeEntry* entry); 1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* FindOrAddChild(CodeEntry* entry); 1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(void IncrementSelfTicks()) { ++self_ticks_; } 144f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke INLINE(void IncreaseSelfTicks(unsigned amount)) { self_ticks_ += amount; } 1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; } 1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry* entry() const) { return entry_; } 1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(unsigned self_ticks() const) { return self_ticks_; } 1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(unsigned total_ticks() const) { return total_ticks_; } 1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const List<ProfileNode*>* children() const) { return &children_list_; } 1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double GetSelfMillis() const; 1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double GetTotalMillis() const; 1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(int indent); 1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 1576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(static bool CodeEntriesMatch(void* entry1, void* entry2)) { 1580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return reinterpret_cast<CodeEntry*>(entry1)->IsSameAs( 1590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen reinterpret_cast<CodeEntry*>(entry2)); 1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(static uint32_t CodeEntryHash(CodeEntry* entry)) { 1630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return entry->GetCallUid(); 1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree* tree_; 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry_; 1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned total_ticks_; 1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned self_ticks_; 1703bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping from CodeEntry* to ProfileNode* 1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HashMap children_; 1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<ProfileNode*> children_list_; 1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileNode); 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTree { 1796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 1806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree(); 1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~ProfileTree(); 1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AddPathFromEnd(const Vector<CodeEntry*>& path); 1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AddPathFromStart(const Vector<CodeEntry*>& path); 1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CalculateTotalTicks(); 186f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void FilteredClone(ProfileTree* src, int security_token_id); 1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double TicksToMillis(unsigned ticks) const { 1896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return ticks * ms_to_ticks_scale_; 1906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root() const { return root_; } 1926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void SetTickRatePerMs(double ticks_per_ms); 1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void ShortPrint(); 1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print() { 1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->Print(0); 1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block template <typename Callback> 201f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke void TraverseDepthFirst(Callback* callback); 2026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry root_entry_; 2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileNode* root_; 2056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double ms_to_ticks_scale_; 2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileTree); 2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfile { 2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CpuProfile(const char* title, unsigned uid) 2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : title_(title), uid_(uid) { } 2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Add pc -> ... -> main() call path to the profile. 2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AddPath(const Vector<CodeEntry*>& path); 2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void CalculateTotalTicks(); 2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void SetActualSamplingRate(double actual_sampling_rate); 220f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CpuProfile* FilteredClone(int security_token_id); 2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const char* title() const) { return title_; } 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(unsigned uid() const) { return uid_; } 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const ProfileTree* top_down() const) { return &top_down_; } 2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(const ProfileTree* bottom_up() const) { return &bottom_up_; } 2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void UpdateTicksScale(); 2286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void ShortPrint(); 2306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* title_; 2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned uid_; 2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree top_down_; 2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ProfileTree bottom_up_; 2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfile); 2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeMap { 2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeMap() : next_shared_id_(1) { } 245589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void AddCode(Address addr, CodeEntry* entry, unsigned size); 246589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void MoveCode(Address from, Address to); 2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* FindEntry(Address addr); 24844f0eee88ff00398ff7f715fab053374d808c90dSteve Block int GetSharedId(Address addr); 2496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Print(); 2516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeEntryInfo { 2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntryInfo(CodeEntry* an_entry, unsigned a_size) 2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : entry(an_entry), size(a_size) { } 2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* entry; 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned size; 2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block struct CodeTreeConfig { 2616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef Address Key; 2626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef CodeEntryInfo Value; 2636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const Key kNoKey; 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const Value NoValue() { return CodeEntryInfo(NULL, 0); } 2656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static int Compare(const Key& a, const Key& b) { 2666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return a < b ? -1 : (a > b ? 1 : 0); 2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block typedef SplayTree<CodeTreeConfig> CodeTree; 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block class CodeTreePrinter { 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Call(const Address& key, const CodeEntryInfo& value); 2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 276589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch void DeleteAllCoveredCode(Address start, Address end); 277589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Fake CodeEntry pointer to distinguish shared function entries. 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block static CodeEntry* const kSharedFunctionCodeEntry; 280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeTree tree_; 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int next_shared_id_; 2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CodeMap); 2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2886ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CpuProfilesCollection { 2896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CpuProfilesCollection(); 2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ~CpuProfilesCollection(); 2926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool StartProfiling(const char* title, unsigned uid); 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool StartProfiling(String* title, unsigned uid); 295f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CpuProfile* StopProfiling(int security_token_id, 296f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke const char* title, 297f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke double actual_sampling_rate); 298f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke List<CpuProfile*>* Profiles(int security_token_id); 2997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* GetName(String* name) { 3007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return function_and_resource_names_.GetName(name); 3017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 302f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const char* GetName(int args_count) { 303f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return function_and_resource_names_.GetName(args_count); 304f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 305f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CpuProfile* GetProfile(int security_token_id, unsigned uid); 306756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bool IsLastProfile(const char* title); 30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveProfile(CpuProfile* profile); 30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool HasDetachedProfiles() { return detached_profiles_.length() > 0; } 3096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 3116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block String* name, String* resource_name, int line_number); 3126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name); 3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 3146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_prefix, String* name); 3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count); 316f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CodeEntry* NewCodeEntry(int security_token_id); 3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Called from profile generator thread. 3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path); 3206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 32180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Limits the number of profiles that can be simultaneously collected. 32280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaxSimultaneousProfiles = 100; 32380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 325791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block const char* GetFunctionName(String* name) { 326791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block return function_and_resource_names_.GetFunctionName(name); 327791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block } 328791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block const char* GetFunctionName(const char* name) { 329791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block return function_and_resource_names_.GetFunctionName(name); 330791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block } 33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int GetProfileIndex(unsigned uid); 332f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke List<CpuProfile*>* GetProfilesList(int security_token_id); 333f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int TokenToIndex(int security_token_id); 3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 335f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke INLINE(static bool UidsMatch(void* key1, void* key2)) { 3366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return key1 == key2; 3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch StringsStorage function_and_resource_names_; 3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CodeEntry*> code_entries_; 341f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke List<List<CpuProfile*>* > profiles_by_token_; 3423bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping from profiles' uids to indexes in the second nested list 3433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // of profiles_by_token_. 3446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HashMap profiles_uids_; 34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<CpuProfile*> detached_profiles_; 3466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Accessed by VM thread and profile generator thread. 3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block List<CpuProfile*> current_profiles_; 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Semaphore* current_profiles_semaphore_; 3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); 3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass SampleRateCalculator { 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SampleRateCalculator() 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : result_(Logger::kSamplingIntervalMs * kResultScale), 3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ticks_per_ms_(Logger::kSamplingIntervalMs), 3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block measurements_count_(0), 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block wall_time_query_countdown_(1) { 3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double ticks_per_ms() { 3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result_ / static_cast<double>(kResultScale); 3666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Tick(); 3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void UpdateMeasurements(double current_time); 3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Instead of querying current wall time each tick, 3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // we use this constant to control query intervals. 3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const unsigned kWallTimeQueryIntervalMs = 100; 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // As the result needs to be accessed from a different thread, we 3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // use type that guarantees atomic writes to memory. There should 3776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // be <= 1000 ticks per second, thus storing a value of a 10 ** 5 3786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // order should provide enough precision while keeping away from a 3796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // potential overflow. 3806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const int kResultScale = 100000; 3816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block AtomicWord result_; 3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // All other fields are accessed only from the sampler thread. 3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double ticks_per_ms_; 3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned measurements_count_; 3866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unsigned wall_time_query_countdown_; 3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block double last_wall_time_; 3887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(SampleRateCalculator); 3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3936ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileGenerator { 3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 3956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block explicit ProfileGenerator(CpuProfilesCollection* profiles); 3966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 3986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block String* name, 3996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block String* resource_name, 4006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_number)) { 4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return profiles_->NewCodeEntry(tag, name, resource_name, line_number); 4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 4056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name)) { 4066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return profiles_->NewCodeEntry(tag, name); 4076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 4106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const char* name_prefix, 4116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block String* name)) { 4126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return profiles_->NewCodeEntry(tag, name_prefix, name); 4136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 4166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int args_count)) { 4176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return profiles_->NewCodeEntry(tag, args_count); 4186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 420f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke INLINE(CodeEntry* NewCodeEntry(int security_token_id)) { 421f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return profiles_->NewCodeEntry(security_token_id); 422f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 423f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 4246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void RecordTickSample(const TickSample& sample); 4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeMap* code_map()) { return &code_map_; } 4276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(void Tick()) { sample_rate_calc_.Tick(); } 4296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(double actual_sampling_rate()) { 4306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return sample_rate_calc_.ticks_per_ms(); 4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kAnonymousFunctionName; 43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kProgramEntryName; 43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* const kGarbageCollectorEntryName; 4366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block INLINE(CodeEntry* EntryForVMState(StateTag tag)); 4396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CpuProfilesCollection* profiles_; 4416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeMap code_map_; 4426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* program_entry_; 4436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CodeEntry* gc_entry_; 4446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SampleRateCalculator sample_rate_calc_; 4456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); 4476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 4486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass HeapEntry; 4517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 452756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass HeapGraphEdge BASE_EMBEDDED { 4537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 4547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch enum Type { 455756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kContextVariable = v8::HeapGraphEdge::kContextVariable, 456756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kElement = v8::HeapGraphEdge::kElement, 457756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kProperty = v8::HeapGraphEdge::kProperty, 4588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang kInternal = v8::HeapGraphEdge::kInternal, 4598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang kHidden = v8::HeapGraphEdge::kHidden, 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kShortcut = v8::HeapGraphEdge::kShortcut, 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kWeak = v8::HeapGraphEdge::kWeak 4627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch }; 4637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 464756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapGraphEdge() { } 465756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void Init(int child_index, Type type, const char* name, HeapEntry* to); 4668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void Init(int child_index, Type type, int index, HeapEntry* to); 467756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void Init(int child_index, int index, HeapEntry* to); 4687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 469756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Type type() { return static_cast<Type>(type_); } 470756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int index() { 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak); 4727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return index_; 4737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 474756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const char* name() { 475756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ASSERT(type_ == kContextVariable 476756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick || type_ == kProperty 4778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang || type_ == kInternal 4788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang || type_ == kShortcut); 4797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return name_; 4807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 481756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* to() { return to_; } 482756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 483756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* From(); 4847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private: 4868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int child_index_ : 29; 4878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang unsigned type_ : 3; 4887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch union { 4897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int index_; 4907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* name_; 4917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch }; 4927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapEntry* to_; 4937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapGraphEdge); 4957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 4967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 498756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass HeapSnapshot; 4997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 500756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapEntry instances represent an entity from the heap (or a special 501756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// virtual node, e.g. root). To make heap snapshots more compact, 502756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapEntries has a special memory layout (no Vectors or Lists used): 503756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// 504756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// +-----------------+ 505756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapEntry 506756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// +-----------------+ 507756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapGraphEdge | 508756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// ... } children_count 509756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapGraphEdge | 510756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// +-----------------+ 511756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapGraphEdge* | 512756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// ... } retainers_count 513756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// HeapGraphEdge* | 514756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// +-----------------+ 515756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// 516756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// In a HeapSnapshot, all entries are hand-allocated in a continuous array 517756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// of raw bytes. 518756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// 519756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass HeapEntry BASE_EMBEDDED { 5207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 5217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch enum Type { 5228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang kHidden = v8::HeapGraphNode::kHidden, 523756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kArray = v8::HeapGraphNode::kArray, 524756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kString = v8::HeapGraphNode::kString, 525756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kObject = v8::HeapGraphNode::kObject, 526756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kCode = v8::HeapGraphNode::kCode, 527f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch kClosure = v8::HeapGraphNode::kClosure, 528f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch kRegExp = v8::HeapGraphNode::kRegExp, 52944f0eee88ff00398ff7f715fab053374d808c90dSteve Block kHeapNumber = v8::HeapGraphNode::kHeapNumber, 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kNative = v8::HeapGraphNode::kNative, 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kSynthetic = v8::HeapGraphNode::kSynthetic 5327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch }; 5337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 534756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry() { } 535756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void Init(HeapSnapshot* snapshot, 5367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Type type, 5377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* name, 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId id, 5397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int self_size, 540756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int children_count, 541756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int retainers_count); 542756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 543756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapSnapshot* snapshot() { return snapshot_; } 544756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Type type() { return static_cast<Type>(type_); } 545756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const char* name() { return name_; } 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void set_name(const char* name) { name_ = name; } 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline SnapshotObjectId id() { return id_; } 548756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int self_size() { return self_size_; } 5498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int retained_size() { return retained_size_; } 5508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void add_retained_size(int size) { retained_size_ += size; } 5518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void set_retained_size(int value) { retained_size_ = value; } 5528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int ordered_index() { return ordered_index_; } 5538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void set_ordered_index(int value) { ordered_index_ = value; } 554756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 555756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Vector<HeapGraphEdge> children() { 556756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return Vector<HeapGraphEdge>(children_arr(), children_count_); } 557756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Vector<HeapGraphEdge*> retainers() { 558756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return Vector<HeapGraphEdge*>(retainers_arr(), retainers_count_); } 5598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* dominator() { return dominator_; } 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void set_dominator(HeapEntry* entry) { 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(entry != NULL); 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dominator_ = entry; 563592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void clear_paint() { painted_ = false; } 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool painted() { return painted_; } 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void paint() { painted_ = true; } 5677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void SetIndexedReference(HeapGraphEdge::Type type, 5698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int child_index, 5708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int index, 5718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* entry, 5728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int retainer_index); 573756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SetNamedReference(HeapGraphEdge::Type type, 574756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int child_index, 575756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const char* name, 576756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* entry, 577756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int retainer_index); 578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SetUnidirElementReference(int child_index, int index, HeapEntry* entry); 579756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size_t EntrySize() { 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return EntriesSize(1, children_count_, retainers_count_); 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Print( 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* prefix, const char* edge_name, int max_depth, int indent); 5867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 58769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<HeapObject> GetHeapObject(); 58869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static size_t EntriesSize(int entries_count, 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int children_count, 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int retainers_count); 5927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 593756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick private: 594756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapGraphEdge* children_arr() { 595756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return reinterpret_cast<HeapGraphEdge*>(this + 1); 596756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 597756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapGraphEdge** retainers_arr() { 598756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return reinterpret_cast<HeapGraphEdge**>(children_arr() + children_count_); 599756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 6007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* TypeAsString(); 6017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned painted_: 1; 60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned type_: 4; 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int children_count_: 27; 605756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int retainers_count_; 6068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int self_size_; 6078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang union { 6088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int ordered_index_; // Used during dominator tree building. 6098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int retained_size_; // At that moment, there is no retained size yet. 6108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang }; 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId id_; 6128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* dominator_; 6137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapSnapshot* snapshot_; 6147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* name_; 615756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 6168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang DISALLOW_COPY_AND_ASSIGN(HeapEntry); 6177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 6187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass HeapSnapshotsCollection; 6217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// HeapSnapshot represents a single heap snapshot. It is stored in 6237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// HeapSnapshotsCollection, which is also a factory for 6247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// HeapSnapshots. All HeapSnapshots share strings copied from JS heap 6257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// to be able to return them even if they were collected. 6267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// HeapSnapshotGenerator fills in a HeapSnapshot. 6277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass HeapSnapshot { 6287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 629791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block enum Type { 6303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kFull = v8::HeapSnapshot::kFull 631791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block }; 632791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 6337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapSnapshot(HeapSnapshotsCollection* collection, 634791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block Type type, 6357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* title, 6367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch unsigned uid); 6373bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch ~HeapSnapshot(); 63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Delete(); 6397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 640756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapSnapshotsCollection* collection() { return collection_; } 641791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block Type type() { return type_; } 642756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const char* title() { return title_; } 643756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick unsigned uid() { return uid_; } 644f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch HeapEntry* root() { return root_entry_; } 6458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* gc_roots() { return gc_roots_entry_; } 64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapEntry* natives_root() { return natives_root_entry_; } 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntry* gc_subroot(int index) { return gc_subroot_entries_[index]; } 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch List<HeapEntry*>* entries() { return &entries_; } 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size_t raw_entries_size() { return raw_entries_size_; } 650756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 651756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void AllocateEntries( 652756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int entries_count, int children_count, int retainers_count); 653791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block HeapEntry* AddEntry(HeapEntry::Type type, 654791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block const char* name, 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId id, 656791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block int size, 657791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block int children_count, 658791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block int retainers_count); 659e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* AddRootEntry(int children_count); 660e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* AddGcRootsEntry(int children_count, int retainers_count); 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntry* AddGcSubrootEntry(int tag, 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int children_count, 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int retainers_count); 66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapEntry* AddNativesRootEntry(int children_count, int retainers_count); 665756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void ClearPaint(); 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntry* GetEntryById(SnapshotObjectId id); 667756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick List<HeapEntry*>* GetSortedEntriesList(); 668756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick template<class Visitor> 669756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void IterateEntries(Visitor* visitor) { entries_.Iterate(visitor); } 6708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void SetDominatorsToSelf(); 6717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void Print(int max_depth); 673756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void PrintEntriesSize(); 674756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 6757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private: 676756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* GetNextEntryToInit(); 6777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapSnapshotsCollection* collection_; 679791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block Type type_; 6807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* title_; 6817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch unsigned uid_; 682f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch HeapEntry* root_entry_; 6838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* gc_roots_entry_; 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapEntry* natives_root_entry_; 6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntry* gc_subroot_entries_[VisitorSynchronization::kNumberOfSyncTags]; 686756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick char* raw_entries_; 687756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick List<HeapEntry*> entries_; 688756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bool entries_sorted_; 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size_t raw_entries_size_; 690756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 691756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick friend class HeapSnapshotTester; 6927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); 6947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 6957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochclass HeapObjectsMap { 6983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch public: 6993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch HeapObjectsMap(); 7003bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch ~HeapObjectsMap(); 7013bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7023bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch void SnapshotGenerationFinished(); 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId FindObject(Address addr); 7043bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch void MoveObject(Address from, Address to); 7053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info); 7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline SnapshotObjectId GetNthGcSubrootId(int delta); 70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kObjectIdStep = 2; 7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const SnapshotObjectId kInternalRootObjectId; 7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const SnapshotObjectId kGcRootsObjectId; 7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const SnapshotObjectId kNativesRootObjectId; 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const SnapshotObjectId kGcRootsFirstSubrootId; 7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const SnapshotObjectId kFirstAvailableObjectId; 7158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch private: 7173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch struct EntryInfo { 7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit EntryInfo(SnapshotObjectId id) : id(id), accessed(true) { } 7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EntryInfo(SnapshotObjectId id, bool accessed) 7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : id(id), 7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accessed(accessed) { } 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId id; 7233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch bool accessed; 7243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch }; 7253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void AddEntry(Address addr, SnapshotObjectId id); 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId FindEntry(Address addr); 7283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch void RemoveDeadEntries(); 7293bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch static bool AddressesMatch(void* key1, void* key2) { 7313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch return key1 == key2; 7323bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 7333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7343bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch static uint32_t AddressHash(Address addr) { 7350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return ComputeIntegerHash( 736c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(addr)), 737c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch v8::internal::kZeroHashSeed); 7383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 7393bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7403bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch bool initial_fill_mode_; 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId next_id_; 7423bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch HashMap entries_map_; 7433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch List<EntryInfo>* entries_; 7443bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7453bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap); 7463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}; 7473bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass HeapSnapshotsCollection { 7507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 7517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapSnapshotsCollection(); 7527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ~HeapSnapshotsCollection(); 7537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7543bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch bool is_tracking_objects() { return is_tracking_objects_; } 7553bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 756791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block HeapSnapshot* NewSnapshot( 757791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block HeapSnapshot::Type type, const char* name, unsigned uid); 758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SnapshotGenerationFinished(HeapSnapshot* snapshot); 7597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch List<HeapSnapshot*>* snapshots() { return &snapshots_; } 7607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapSnapshot* GetSnapshot(unsigned uid); 76144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RemoveSnapshot(HeapSnapshot* snapshot); 7627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block StringsStorage* names() { return &names_; } 7647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TokenEnumerator* token_enumerator() { return token_enumerator_; } 7657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SnapshotObjectId GetObjectId(Address addr) { return ids_.FindObject(addr); } 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id); 7683bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch void ObjectMoveEvent(Address from, Address to) { ids_.MoveObject(from, to); } 7693bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private: 7717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) { 7727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return key1 == key2; 7737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 7747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch bool is_tracking_objects_; // Whether tracking object moves is needed. 7767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch List<HeapSnapshot*> snapshots_; 7773bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping from snapshots' uids to HeapSnapshot* pointers. 7787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HashMap snapshots_uids_; 7797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch StringsStorage names_; 7807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TokenEnumerator* token_enumerator_; 7813bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Mapping from HeapObject addresses to objects' uids. 7823bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch HeapObjectsMap ids_; 7837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection); 7857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 7867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 788e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// A typedef for referencing anything that can be snapshotted living 789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// in any kind of heap memory. 790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochtypedef void* HeapThing; 791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 792e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 793e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// An interface that creates HeapEntries by HeapThings. 794e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass HeapEntriesAllocator { 795e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 796e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual ~HeapEntriesAllocator() { } 797e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual HeapEntry* AllocateEntry( 798e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing ptr, int children_count, int retainers_count) = 0; 799e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 800e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 802756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// The HeapEntriesMap instance is used to track a mapping between 803756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// real heap objects and their representations in heap snapshots. 804756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass HeapEntriesMap { 805756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public: 806756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntriesMap(); 807756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ~HeapEntriesMap(); 808756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 809e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void AllocateEntries(); 810e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* Map(HeapThing thing); 811e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry); 812e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void CountReference(HeapThing from, HeapThing to, 813756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int* prev_children_count = NULL, 814756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int* prev_retainers_count = NULL); 815756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 816756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int entries_count() { return entries_count_; } 817756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int total_children_count() { return total_children_count_; } 818756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int total_retainers_count() { return total_retainers_count_; } 819756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 8203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static HeapEntry* const kHeapEntryPlaceholder; 821791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 822756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick private: 823756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick struct EntryInfo { 824e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch EntryInfo(HeapEntry* entry, HeapEntriesAllocator* allocator) 825e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : entry(entry), 826e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch allocator(allocator), 827e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch children_count(0), 828e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainers_count(0) { 829e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 830756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* entry; 831e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntriesAllocator* allocator; 832756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int children_count; 833756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int retainers_count; 834756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick }; 835756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 836e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static uint32_t Hash(HeapThing thing) { 8370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return ComputeIntegerHash( 838c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)), 839c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch v8::internal::kZeroHashSeed); 840e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 841e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static bool HeapThingsMatch(HeapThing key1, HeapThing key2) { 842e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return key1 == key2; 843756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 844756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 845756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HashMap entries_; 846756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int entries_count_; 847756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int total_children_count_; 848756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int total_retainers_count_; 849756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 8508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang friend class HeapObjectsSet; 851756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 852756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); 853756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}; 854756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 855756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 8568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangclass HeapObjectsSet { 8578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang public: 8588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapObjectsSet(); 8598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void Clear(); 8608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang bool Contains(Object* object); 8618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void Insert(Object* obj); 8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* GetTag(Object* obj); 8633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void SetTag(Object* obj, const char* tag); 8648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 8658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang private: 8668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HashMap entries_; 8678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 8688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet); 8698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}; 8708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 8718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 872e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// An interface used to populate a snapshot with nodes and edges. 873e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass SnapshotFillerInterface { 8747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 875e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual ~SnapshotFillerInterface() { } 87644f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual HeapEntry* AddEntry(HeapThing ptr, 87744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapEntriesAllocator* allocator) = 0; 87844f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual HeapEntry* FindEntry(HeapThing ptr) = 0; 87944f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual HeapEntry* FindOrAddEntry(HeapThing ptr, 88044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapEntriesAllocator* allocator) = 0; 881e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void SetIndexedReference(HeapGraphEdge::Type type, 882e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing parent_ptr, 883756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* parent_entry, 884e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int index, 885e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing child_ptr, 886756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* child_entry) = 0; 887e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, 888e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing parent_ptr, 889e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* parent_entry, 890e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing child_ptr, 891e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* child_entry) = 0; 892e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void SetNamedReference(HeapGraphEdge::Type type, 893e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing parent_ptr, 894e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* parent_entry, 895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* reference_name, 896e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing child_ptr, 897e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* child_entry) = 0; 898e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type, 899e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing parent_ptr, 900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* parent_entry, 901e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing child_ptr, 9028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* child_entry) = 0; 903e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 904756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 905e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 906e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass SnapshottingProgressReportingInterface { 907e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 908e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual ~SnapshottingProgressReportingInterface() { } 909e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void ProgressStep() = 0; 910e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual bool ProgressReport(bool force) = 0; 911e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 912e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 913e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 914e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// An implementation of V8 heap graph extractor. 915e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass V8HeapExplorer : public HeapEntriesAllocator { 916e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch V8HeapExplorer(HeapSnapshot* snapshot, 918e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SnapshottingProgressReportingInterface* progress); 91944f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual ~V8HeapExplorer(); 920e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual HeapEntry* AllocateEntry( 921e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapThing ptr, int children_count, int retainers_count); 922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void AddRootEntries(SnapshotFillerInterface* filler); 9233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int EstimateObjectsCount(HeapIterator* iterator); 924e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool IterateAndExtractReferences(SnapshotFillerInterface* filler); 9253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool IterateAndSetObjectNames(SnapshotFillerInterface* filler); 9263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void TagGlobalObjects(); 9277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 92869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static String* GetConstructorName(JSObject* object); 92969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 93044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static HeapObject* const kInternalRootObject; 93144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private: 933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* AddEntry( 934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* object, int children_count, int retainers_count); 935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* AddEntry(HeapObject* object, 936e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry::Type type, 937e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* name, 938e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int children_count, 939e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int retainers_count); 9408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch const char* GetSystemEntryName(HeapObject* object); 9417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void ExtractReferences(HeapObject* obj); 9427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); 9437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); 9447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); 945f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); 946756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SetClosureReference(HeapObject* parent_obj, 947756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* parent, 948756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick String* reference_name, 949756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object* child); 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetNativeBindReference(HeapObject* parent_obj, 9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntry* parent, 9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* reference_name, 9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* child); 954756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SetElementReference(HeapObject* parent_obj, 955756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* parent, 956756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick int index, 957756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object* child); 958756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SetInternalReference(HeapObject* parent_obj, 959756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* parent, 960756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const char* reference_name, 96144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* child, 96244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int field_offset = -1); 963f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void SetInternalReference(HeapObject* parent_obj, 964f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch HeapEntry* parent, 965f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch int index, 96644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* child, 96744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int field_offset = -1); 9688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void SetHiddenReference(HeapObject* parent_obj, 9698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* parent, 9708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int index, 9718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Object* child); 9723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetWeakReference(HeapObject* parent_obj, 9733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntry* parent_entry, 9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index, 9753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* child_obj, 9763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int field_offset); 977756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void SetPropertyReference(HeapObject* parent_obj, 978756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapEntry* parent, 979756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick String* reference_name, 98044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* child, 9813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* name_format_string = NULL, 98244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int field_offset = -1); 9838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void SetPropertyShortcutReference(HeapObject* parent_obj, 9848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang HeapEntry* parent, 9858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang String* reference_name, 9868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Object* child); 9878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void SetRootShortcutReference(Object* child); 9888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang void SetRootGcRootsReference(); 9893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetGcRootsReference(VisitorSynchronization::SyncTag tag); 9903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetGcSubrootReference( 9913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitorSynchronization::SyncTag tag, bool is_weak, Object* child); 9923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetObjectName(HeapObject* object); 9933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void TagObject(Object* obj, const char* tag); 994e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 995e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntry* GetEntry(Object* obj); 9967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline HeapObject* GetNthGcSubrootObject(int delta); 9983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline int GetGcSubrootOrder(HeapObject* subroot); 9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap* heap_; 10017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch HeapSnapshot* snapshot_; 1002756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick HeapSnapshotsCollection* collection_; 1003e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SnapshottingProgressReportingInterface* progress_; 1004e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SnapshotFillerInterface* filler_; 10053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HeapObjectsSet objects_tags_; 1006e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1007e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static HeapObject* const kGcRootsObject; 10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static HeapObject* const kFirstGcSubrootObject; 10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static HeapObject* const kLastGcSubrootObject; 1010756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1011756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick friend class IndexedReferencesExtractor; 10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class GcSubrootsEnumerator; 10138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang friend class RootsReferencesExtractor; 10147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1015e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer); 1016e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 1017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass NativeGroupRetainedObjectInfo; 10203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 102244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// An implementation of retained native objects extractor. 10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass NativeObjectsExplorer { 102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 102544f0eee88ff00398ff7f715fab053374d808c90dSteve Block NativeObjectsExplorer(HeapSnapshot* snapshot, 102644f0eee88ff00398ff7f715fab053374d808c90dSteve Block SnapshottingProgressReportingInterface* progress); 102744f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual ~NativeObjectsExplorer(); 102844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void AddRootEntries(SnapshotFillerInterface* filler); 102944f0eee88ff00398ff7f715fab053374d808c90dSteve Block int EstimateObjectsCount(); 103044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IterateAndExtractReferences(SnapshotFillerInterface* filler); 103144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 103244f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 103344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void FillRetainedObjects(); 10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void FillImplicitReferences(); 103544f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<HeapObject*>* GetListMaybeDisposeInfo(v8::RetainedObjectInfo* info); 103644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void SetNativeRootReference(v8::RetainedObjectInfo* info); 10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SetRootNativeRootsReference(); 103844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void SetWrapperNativeReferences(HeapObject* wrapper, 103944f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::RetainedObjectInfo* info); 104044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void VisitSubtreeWrapper(Object** p, uint16_t class_id); 104144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 104244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static uint32_t InfoHash(v8::RetainedObjectInfo* info) { 1043c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()), 1044c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch v8::internal::kZeroHashSeed); 104544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 104644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static bool RetainedInfosMatch(void* key1, void* key2) { 104744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return key1 == key2 || 104844f0eee88ff00398ff7f715fab053374d808c90dSteve Block (reinterpret_cast<v8::RetainedObjectInfo*>(key1))->IsEquivalent( 104944f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<v8::RetainedObjectInfo*>(key2)); 105044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INLINE(static bool StringsMatch(void* key1, void* key2)) { 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return strcmp(reinterpret_cast<char*>(key1), 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<char*>(key2)) == 0; 10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NativeGroupRetainedObjectInfo* FindOrAddGroupInfo(const char* label); 105744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 105844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapSnapshot* snapshot_; 105944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapSnapshotsCollection* collection_; 106044f0eee88ff00398ff7f715fab053374d808c90dSteve Block SnapshottingProgressReportingInterface* progress_; 106144f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool embedder_queried_; 106244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapObjectsSet in_groups_; 106344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // RetainedObjectInfo* -> List<HeapObject*>* 106444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HashMap objects_by_info_; 10653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HashMap native_groups_; 10663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntriesAllocator* synthetic_entries_allocator_; 10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapEntriesAllocator* native_entries_allocator_; 106844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Used during references extraction. 106944f0eee88ff00398ff7f715fab053374d808c90dSteve Block SnapshotFillerInterface* filler_; 107044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 107144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static HeapThing const kNativesRootObject; 107244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class GlobalHandlesExtractor; 107444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 107544f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer); 107644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 107744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 107844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1079e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { 1080e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 1081e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapSnapshotGenerator(HeapSnapshot* snapshot, 1082e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v8::ActivityControl* control); 1083e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool GenerateSnapshot(); 1084e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1085e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 1086e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool BuildDominatorTree(const Vector<HeapEntry*>& entries, 10873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<int>* dominators); 10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool CalculateRetainedSizes(); 1089e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool CountEntriesAndReferences(); 1090e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool FillReferences(); 1091e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void FillReversePostorderIndexes(Vector<HeapEntry*>* entries); 1092e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void ProgressStep(); 1093e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool ProgressReport(bool force = false); 1094e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool SetEntriesDominators(); 1095e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void SetProgressTotal(int iterations_count); 1096e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1097e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapSnapshot* snapshot_; 1098e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v8::ActivityControl* control_; 1099e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch V8HeapExplorer v8_heap_explorer_; 110044f0eee88ff00398ff7f715fab053374d808c90dSteve Block NativeObjectsExplorer dom_explorer_; 1101e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Mapping from HeapThing pointers to HeapEntry* pointers. 1102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapEntriesMap entries_; 1103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Used during snapshot generation. 1104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int progress_counter_; 1105e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int progress_total_; 1106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 11077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); 11087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 11097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 11100d5e116f6aee03185f237311a943491bb079a768Kristian Monsenclass OutputStreamWriter; 11110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11120d5e116f6aee03185f237311a943491bb079a768Kristian Monsenclass HeapSnapshotJSONSerializer { 11130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 11140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot) 11150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : snapshot_(snapshot), 11160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen nodes_(ObjectsMatch), 11170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen strings_(ObjectsMatch), 11180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen next_node_id_(1), 11190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen next_string_id_(1), 11200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen writer_(NULL) { 11210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 11220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void Serialize(v8::OutputStream* stream); 11230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 11250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE(static bool ObjectsMatch(void* key1, void* key2)) { 11260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return key1 == key2; 11270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 11280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE(static uint32_t ObjectHash(const void* key)) { 11300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return ComputeIntegerHash( 1131c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)), 1132c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch v8::internal::kZeroHashSeed); 11330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 11340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void EnumerateNodes(); 113669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HeapSnapshot* CreateFakeSnapshot(); 11370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int GetNodeId(HeapEntry* entry); 11380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int GetStringId(const char* s); 11390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeEdge(HeapGraphEdge* edge); 11400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeImpl(); 11410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeNode(HeapEntry* entry); 11420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeNodes(); 11430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeSnapshot(); 11440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeString(const unsigned char* s); 11450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SerializeStrings(); 11460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries); 11470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 114869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static const int kMaxSerializableSnapshotRawSize; 114969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen HeapSnapshot* snapshot_; 11510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen HashMap nodes_; 11520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen HashMap strings_; 11530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int next_node_id_; 11540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int next_string_id_; 11550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen OutputStreamWriter* writer_; 11560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen friend class HeapSnapshotJSONSerializerEnumerator; 11580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen friend class HeapSnapshotJSONSerializerIterator; 11590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer); 11610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 11620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 11636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} } // namespace v8::internal 11646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 11656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_PROFILE_GENERATOR_H_ 1166