1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_PROFILER_HEAP_SNAPSHOT_GENERATOR_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_PROFILER_HEAP_SNAPSHOT_GENERATOR_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include <deque> 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <unordered_map> 10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "include/v8-profiler.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/platform/time.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/strings-storage.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AllocationTracker; 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AllocationTraceNode; 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapEntry; 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HeapIterator; 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HeapProfiler; 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapSnapshot; 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SnapshotFiller; 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapGraphEdge BASE_EMBEDDED { 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum Type { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kContextVariable = v8::HeapGraphEdge::kContextVariable, 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kElement = v8::HeapGraphEdge::kElement, 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kProperty = v8::HeapGraphEdge::kProperty, 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kInternal = v8::HeapGraphEdge::kInternal, 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kHidden = v8::HeapGraphEdge::kHidden, 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kShortcut = v8::HeapGraphEdge::kShortcut, 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kWeak = v8::HeapGraphEdge::kWeak 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapGraphEdge(Type type, const char* name, int from, int to); 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapGraphEdge(Type type, int index, int from, int to); 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ReplaceToIndexWithEntry(HeapSnapshot* snapshot); 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Type type() const { return TypeField::decode(bit_field_); } 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index() const { 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(type() == kElement || type() == kHidden); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return index_; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name() const { 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(type() == kContextVariable || type() == kProperty || 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier type() == kInternal || type() == kShortcut || type() == kWeak); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return name_; 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(HeapEntry* from() const); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* to() const { return to_entry_; } 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(Isolate* isolate() const); 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(HeapSnapshot* snapshot() const); 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int from_index() const { return FromIndexField::decode(bit_field_); } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class TypeField : public BitField<Type, 0, 3> {}; 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier class FromIndexField : public BitField<int, 3, 29> {}; 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t bit_field_; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch union { 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // During entries population |to_index_| is used for storing the index, 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // afterwards it is replaced with a pointer to the entry. 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int to_index_; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* to_entry_; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch union { 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index_; 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_; 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HeapEntry instances represent an entity from the heap (or a special 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// virtual node, e.g. root). 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapEntry BASE_EMBEDDED { 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum Type { 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kHidden = v8::HeapGraphNode::kHidden, 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kArray = v8::HeapGraphNode::kArray, 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kString = v8::HeapGraphNode::kString, 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kObject = v8::HeapGraphNode::kObject, 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCode = v8::HeapGraphNode::kCode, 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kClosure = v8::HeapGraphNode::kClosure, 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kRegExp = v8::HeapGraphNode::kRegExp, 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kHeapNumber = v8::HeapGraphNode::kHeapNumber, 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNative = v8::HeapGraphNode::kNative, 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kSynthetic = v8::HeapGraphNode::kSynthetic, 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kConsString = v8::HeapGraphNode::kConsString, 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kSlicedString = v8::HeapGraphNode::kSlicedString, 9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kSymbol = v8::HeapGraphNode::kSymbol 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kNoEntry; 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry() { } 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry(HeapSnapshot* snapshot, 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type type, 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name, 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId id, 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t self_size, 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned trace_node_id); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshot* snapshot() { return snapshot_; } 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type type() { return static_cast<Type>(type_); } 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name() { return name_; } 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_name(const char* name) { name_ = name; } 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId id() { return id_; } 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t self_size() { return self_size_; } 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned trace_node_id() const { return trace_node_id_; } 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(int index() const); 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int children_count() const { return children_count_; } 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(int set_children_index(int index)); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void add_child(HeapGraphEdge* edge) { 11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch *(children_begin() + children_count_++) = edge; 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HeapGraphEdge* child(int i) { return *(children_begin() + i); } 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INLINE(Isolate* isolate() const); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetIndexedReference( 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapGraphEdge::Type type, int index, HeapEntry* entry); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetNamedReference( 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapGraphEdge::Type type, const char* name, HeapEntry* entry); 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Print( 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* prefix, const char* edge_name, int max_depth, int indent); 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch INLINE(std::deque<HeapGraphEdge*>::iterator children_begin()); 13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch INLINE(std::deque<HeapGraphEdge*>::iterator children_end()); 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* TypeAsString(); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned type_: 4; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int children_count_: 28; 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int children_index_; 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t self_size_; 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshot* snapshot_; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId id_; 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // id of allocation stack trace top node 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned trace_node_id_; 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HeapSnapshot represents a single heap snapshot. It is stored in 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HeapProfiler, which is also a factory for 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HeapSnapshots. All HeapSnapshots share strings copied from JS heap 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to be able to return them even if they were collected. 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HeapSnapshotGenerator fills in a HeapSnapshot. 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapSnapshot { 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit HeapSnapshot(HeapProfiler* profiler); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Delete(); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapProfiler* profiler() { return profiler_; } 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t RawSnapshotSize() const; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* root() { return &entries_[root_index_]; } 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* gc_roots() { return &entries_[gc_roots_index_]; } 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* gc_subroot(int index) { 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return &entries_[gc_subroot_indexes_[index]]; 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<HeapEntry>& entries() { return entries_; } 16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::deque<HeapGraphEdge>& edges() { return edges_; } 16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::deque<HeapGraphEdge*>& children() { return children_; } 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RememberLastJSObjectId(); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId max_snapshot_js_object_id() const { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return max_snapshot_js_object_id_; 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddEntry(HeapEntry::Type type, 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name, 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId id, 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t size, 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned trace_node_id); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddSyntheticRootEntries(); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* GetEntryById(SnapshotObjectId id); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<HeapEntry*>* GetSortedEntriesList(); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FillChildren(); 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Print(int max_depth); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddRootEntry(); 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddGcRootsEntry(); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddGcSubrootEntry(int tag, SnapshotObjectId id); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapProfiler* profiler_; 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int root_index_; 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int gc_roots_index_; 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int gc_subroot_indexes_[VisitorSynchronization::kNumberOfSyncTags]; 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<HeapEntry> entries_; 19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::deque<HeapGraphEdge> edges_; 19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::deque<HeapGraphEdge*> children_; 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<HeapEntry*> sorted_entries_; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId max_snapshot_js_object_id_; 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class HeapSnapshotTester; 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapObjectsMap { 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch struct TimeInterval { 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit TimeInterval(SnapshotObjectId id) 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : id(id), size(0), count(0), timestamp(base::TimeTicks::Now()) {} 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SnapshotObjectId last_assigned_id() const { return id - kObjectIdStep; } 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SnapshotObjectId id; 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t size; 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t count; 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::TimeTicks timestamp; 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit HeapObjectsMap(Heap* heap); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap() const { return heap_; } 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId FindEntry(Address addr); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId FindOrAddEntry(Address addr, 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int size, 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool accessed = true); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool MoveObject(Address from, Address to, int size); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UpdateObjectSize(Address addr, int size); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId last_assigned_id() const { 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next_id_ - kObjectIdStep; 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StopHeapObjectsTracking(); 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SnapshotObjectId PushHeapObjectsStats(OutputStream* stream, 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t* timestamp_us); 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const List<TimeInterval>& samples() const { return time_intervals_; } 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t GetUsedMemorySize() const; 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kObjectIdStep = 2; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const SnapshotObjectId kInternalRootObjectId; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const SnapshotObjectId kGcRootsObjectId; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const SnapshotObjectId kGcRootsFirstSubrootId; 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const SnapshotObjectId kFirstAvailableObjectId; 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int FindUntrackedObjects(); 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UpdateHeapObjectsMap(); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RemoveDeadEntries(); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct EntryInfo { 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EntryInfo(SnapshotObjectId id, Address addr, unsigned int size) 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : id(id), addr(addr), size(size), accessed(true) { } 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EntryInfo(SnapshotObjectId id, Address addr, unsigned int size, bool accessed) 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : id(id), addr(addr), size(size), accessed(accessed) { } 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId id; 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address addr; 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int size; 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool accessed; 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotObjectId next_id_; 26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap entries_map_; 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<EntryInfo> entries_; 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<TimeInterval> time_intervals_; 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap); 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A typedef for referencing anything that can be snapshotted living 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in any kind of heap memory. 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef void* HeapThing; 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An interface that creates HeapEntries by HeapThings. 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapEntriesAllocator { 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~HeapEntriesAllocator() { } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0; 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The HeapEntriesMap instance is used to track a mapping between 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// real heap objects and their representations in heap snapshots. 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapEntriesMap { 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntriesMap(); 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int Map(HeapThing thing); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Pair(HeapThing thing, int entry); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t Hash(HeapThing thing) { 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ComputeIntegerHash( 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)), 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::kZeroHashSeed); 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap entries_; 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class HeapObjectsSet; 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapObjectsSet { 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectsSet(); 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Clear(); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Contains(Object* object); 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Insert(Object* obj); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetTag(Object* obj); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetTag(Object* obj, const char* tag); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_empty() const { return entries_.occupancy() == 0; } 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 32113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap entries_; 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SnapshottingProgressReportingInterface { 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~SnapshottingProgressReportingInterface() { } 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void ProgressStep() = 0; 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual bool ProgressReport(bool force) = 0; 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An implementation of V8 heap graph extractor. 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass V8HeapExplorer : public HeapEntriesAllocator { 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V8HeapExplorer(HeapSnapshot* snapshot, 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshottingProgressReportingInterface* progress, 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler::ObjectNameResolver* resolver); 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~V8HeapExplorer(); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual HeapEntry* AllocateEntry(HeapThing ptr); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int EstimateObjectsCount(HeapIterator* iterator); 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IterateAndExtractReferences(SnapshotFiller* filler); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TagGlobalObjects(); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TagCodeObject(Code* code); 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TagBuiltinCodeObject(Code* code, const char* name); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddEntry(Address address, 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry::Type type, 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name, 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t size); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static String* GetConstructorName(JSObject* object); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef bool (V8HeapExplorer::*ExtractReferencesMethod)(int entry, 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObject* object); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkVisitedField(HeapObject* obj, int offset); 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddEntry(HeapObject* object); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* AddEntry(HeapObject* object, 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry::Type type, 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetSystemEntryName(HeapObject* object); 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<V8HeapExplorer::ExtractReferencesMethod extractor> 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IterateAndExtractSinglePass(); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ExtractReferencesPass1(int entry, HeapObject* obj); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ExtractReferencesPass2(int entry, HeapObject* obj); 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractJSGlobalProxyReferences(int entry, JSGlobalProxy* proxy); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractJSObjectReferences(int entry, JSObject* js_obj); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractStringReferences(int entry, String* obj); 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractSymbolReferences(int entry, Symbol* symbol); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractJSCollectionReferences(int entry, JSCollection* collection); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractJSWeakCollectionReferences(int entry, 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSWeakCollection* collection); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractContextReferences(int entry, Context* context); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractMapReferences(int entry, Map* map); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractSharedFunctionInfoReferences(int entry, 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractScriptReferences(int entry, Script* script); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractAccessorInfoReferences(int entry, AccessorInfo* accessor_info); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractAccessorPairReferences(int entry, AccessorPair* accessors); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractCodeReferences(int entry, Code* code); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractCellReferences(int entry, Cell* cell); 389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ExtractWeakCellReferences(int entry, WeakCell* weak_cell); 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractPropertyCellReferences(int entry, PropertyCell* cell); 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractAllocationSiteReferences(int entry, AllocationSite* site); 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractJSArrayBufferReferences(int entry, JSArrayBuffer* buffer); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractFixedArrayReferences(int entry, FixedArray* array); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractPropertyReferences(JSObject* js_obj, int entry); 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ExtractAccessorPairProperty(JSObject* js_obj, int entry, Name* key, 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* callback_obj, int field_offset = -1); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractElementReferences(JSObject* js_obj, int entry); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ExtractInternalReferences(JSObject* js_obj, int entry); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsEssentialObject(Object* object); 401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool IsEssentialHiddenReference(Object* parent, int field_offset); 402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetContextReference(HeapObject* parent_obj, 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String* reference_name, 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child, 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetNativeBindReference(HeapObject* parent_obj, 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* reference_name, 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetElementReference(HeapObject* parent_obj, 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index, 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child); 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetInternalReference(HeapObject* parent_obj, 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* reference_name, 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child, 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset = -1); 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetInternalReference(HeapObject* parent_obj, 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index, 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child, 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset = -1); 426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SetHiddenReference(HeapObject* parent_obj, int parent, int index, 427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* child, int field_offset); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetWeakReference(HeapObject* parent_obj, 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* reference_name, 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child_obj, 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset); 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetWeakReference(HeapObject* parent_obj, 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index, 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child_obj, 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset); 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetPropertyReference(HeapObject* parent_obj, 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parent, 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Name* reference_name, 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* child, 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name_format_string = NULL, 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int field_offset = -1); 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void SetDataOrAccessorPropertyReference(PropertyKind kind, 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSObject* parent_obj, int parent, 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Name* reference_name, Object* child, 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const char* name_format_string = NULL, 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int field_offset = -1); 449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetUserGlobalReference(Object* user_global); 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetRootGcRootsReference(); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetGcRootsReference(VisitorSynchronization::SyncTag tag); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetGcSubrootReference( 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitorSynchronization::SyncTag tag, bool is_weak, Object* child); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* GetStrongGcSubrootName(Object* object); 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TagObject(Object* obj, const char* tag); 457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void TagFixedArraySubType(const FixedArray* array, 458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArraySubInstanceType type); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntry* GetEntry(Object* obj); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshot* snapshot_; 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StringsStorage* names_; 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectsMap* heap_object_map_; 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshottingProgressReportingInterface* progress_; 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotFiller* filler_; 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectsSet objects_tags_; 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectsSet strong_gc_subroot_names_; 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectsSet user_roots_; 471f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unordered_map<const FixedArray*, FixedArraySubInstanceType> array_types_; 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_; 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch std::vector<bool> marks_; 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class IndexedReferencesExtractor; 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class RootsReferencesExtractor; 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer); 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NativeGroupRetainedObjectInfo; 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An implementation of retained native objects extractor. 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NativeObjectsExplorer { 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeObjectsExplorer(HeapSnapshot* snapshot, 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshottingProgressReportingInterface* progress); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~NativeObjectsExplorer(); 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int EstimateObjectsCount(); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IterateAndExtractReferences(SnapshotFiller* filler); 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FillRetainedObjects(); 49762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void FillEdges(); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<HeapObject*>* GetListMaybeDisposeInfo(v8::RetainedObjectInfo* info); 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetNativeRootReference(v8::RetainedObjectInfo* info); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetRootNativeRootsReference(); 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetWrapperNativeReferences(HeapObject* wrapper, 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::RetainedObjectInfo* info); 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitSubtreeWrapper(Object** p, uint16_t class_id); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static uint32_t InfoHash(v8::RetainedObjectInfo* info) { 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()), 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::kZeroHashSeed); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool RetainedInfosMatch(void* key1, void* key2) { 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return key1 == key2 || 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (reinterpret_cast<v8::RetainedObjectInfo*>(key1))->IsEquivalent( 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<v8::RetainedObjectInfo*>(key2)); 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool StringsMatch(void* key1, void* key2)) { 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return strcmp(reinterpret_cast<char*>(key1), 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<char*>(key2)) == 0; 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeGroupRetainedObjectInfo* FindOrAddGroupInfo(const char* label); 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshot* snapshot_; 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StringsStorage* names_; 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool embedder_queried_; 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapObjectsSet in_groups_; 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // RetainedObjectInfo* -> List<HeapObject*>* 527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch base::CustomMatcherHashMap objects_by_info_; 528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch base::CustomMatcherHashMap native_groups_; 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntriesAllocator* synthetic_entries_allocator_; 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntriesAllocator* native_entries_allocator_; 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Used during references extraction. 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SnapshotFiller* filler_; 53362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::HeapProfiler::RetainerEdges edges_; 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static HeapThing const kNativesRootObject; 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class GlobalHandlesExtractor; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer); 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshotGenerator(HeapSnapshot* snapshot, 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ActivityControl* control, 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler::ObjectNameResolver* resolver, 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap); 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GenerateSnapshot(); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool FillReferences(); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ProgressStep(); 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool ProgressReport(bool force = false); 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetProgressTotal(int iterations_count); 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshot* snapshot_; 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ActivityControl* control_; 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V8HeapExplorer v8_heap_explorer_; 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeObjectsExplorer dom_explorer_; 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mapping from HeapThing pointers to HeapEntry* pointers. 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapEntriesMap entries_; 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Used during snapshot generation. 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int progress_counter_; 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int progress_total_; 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap_; 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass OutputStreamWriter; 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapSnapshotJSONSerializer { 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot) 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : snapshot_(snapshot), 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch strings_(StringsMatch), 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_node_id_(1), 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_string_id_(1), 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch writer_(NULL) { 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Serialize(v8::OutputStream* stream); 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static bool StringsMatch(void* key1, void* key2)) { 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return strcmp(reinterpret_cast<char*>(key1), 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<char*>(key2)) == 0; 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE(static uint32_t StringHash(const void* string)) { 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* s = reinterpret_cast<const char*>(string); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int len = static_cast<int>(strlen(s)); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return StringHasher::HashSequentialString( 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch s, len, v8::internal::kZeroHashSeed); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int GetStringId(const char* s); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int entry_index(HeapEntry* e) { return e->index() * kNodeFieldsCount; } 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeEdge(HeapGraphEdge* edge, bool first_edge); 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeEdges(); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeImpl(); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeNode(HeapEntry* entry); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeNodes(); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeSnapshot(); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeTraceTree(); 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeTraceNode(AllocationTraceNode* node); 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeTraceNodeInfos(); 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SerializeSamples(); 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeString(const unsigned char* s); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SerializeStrings(); 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kEdgeFieldsCount; 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kNodeFieldsCount; 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapSnapshot* snapshot_; 616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch base::CustomMatcherHashMap strings_; 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int next_node_id_; 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int next_string_id_; 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OutputStreamWriter* writer_; 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class HeapSnapshotJSONSerializerEnumerator; 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class HeapSnapshotJSONSerializerIterator; 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer); 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_PROFILER_HEAP_SNAPSHOT_GENERATOR_H_ 632