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