12e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
42e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
52e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#ifndef V8_HEAP_SNAPSHOT_GENERATOR_H_
62e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#define V8_HEAP_SNAPSHOT_GENERATOR_H_
72e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/profile-generator-inl.h"
9c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgnamespace v8 {
112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgnamespace internal {
122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
13b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgclass AllocationTracker;
14b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgclass AllocationTraceNode;
152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapEntry;
162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapSnapshot;
17381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.orgclass SnapshotFiller;
182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapGraphEdge BASE_EMBEDDED {
202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  enum Type {
222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kContextVariable = v8::HeapGraphEdge::kContextVariable,
232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kElement = v8::HeapGraphEdge::kElement,
242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kProperty = v8::HeapGraphEdge::kProperty,
252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kInternal = v8::HeapGraphEdge::kInternal,
262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kHidden = v8::HeapGraphEdge::kHidden,
272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kShortcut = v8::HeapGraphEdge::kShortcut,
282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kWeak = v8::HeapGraphEdge::kWeak
292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapGraphEdge() { }
322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapGraphEdge(Type type, const char* name, int from, int to);
332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapGraphEdge(Type type, int index, int from, int to);
342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ReplaceToIndexWithEntry(HeapSnapshot* snapshot);
352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Type type() const { return static_cast<Type>(type_); }
372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int index() const {
38e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(type_ == kElement || type_ == kHidden);
392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return index_;
402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* name() const {
42e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(type_ == kContextVariable
432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        || type_ == kProperty
442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        || type_ == kInternal
45af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        || type_ == kShortcut
46af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        || type_ == kWeak);
472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return name_;
482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  INLINE(HeapEntry* from() const);
502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* to() const { return to_entry_; }
512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  INLINE(HeapSnapshot* snapshot() const);
542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned type_ : 3;
562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int from_index_ : 29;
572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  union {
582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // During entries population |to_index_| is used for storing the index,
592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // afterwards it is replaced with a pointer to the entry.
602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    int to_index_;
612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HeapEntry* to_entry_;
622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  union {
642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    int index_;
652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    const char* name_;
662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// HeapEntry instances represent an entity from the heap (or a special
712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// virtual node, e.g. root).
722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapEntry BASE_EMBEDDED {
732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  enum Type {
752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kHidden = v8::HeapGraphNode::kHidden,
762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kArray = v8::HeapGraphNode::kArray,
772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kString = v8::HeapGraphNode::kString,
782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kObject = v8::HeapGraphNode::kObject,
792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kCode = v8::HeapGraphNode::kCode,
802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kClosure = v8::HeapGraphNode::kClosure,
812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kRegExp = v8::HeapGraphNode::kRegExp,
822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kHeapNumber = v8::HeapGraphNode::kHeapNumber,
832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    kNative = v8::HeapGraphNode::kNative,
84c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    kSynthetic = v8::HeapGraphNode::kSynthetic,
85c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    kConsString = v8::HeapGraphNode::kConsString,
86fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    kSlicedString = v8::HeapGraphNode::kSlicedString,
87fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    kSymbol = v8::HeapGraphNode::kSymbol
882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const int kNoEntry;
902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry() { }
922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry(HeapSnapshot* snapshot,
932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            Type type,
942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            const char* name,
952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            SnapshotObjectId id,
96ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org            size_t self_size,
97ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org            unsigned trace_node_id);
982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshot* snapshot() { return snapshot_; }
1002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Type type() { return static_cast<Type>(type_); }
1012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* name() { return name_; }
1022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void set_name(const char* name) { name_ = name; }
10306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  SnapshotObjectId id() { return id_; }
104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  size_t self_size() { return self_size_; }
105ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  unsigned trace_node_id() const { return trace_node_id_; }
1062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  INLINE(int index() const);
1072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int children_count() const { return children_count_; }
1082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  INLINE(int set_children_index(int index));
1092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void add_child(HeapGraphEdge* edge) {
1102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    children_arr()[children_count_++] = edge;
1112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
1122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Vector<HeapGraphEdge*> children() {
1132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return Vector<HeapGraphEdge*>(children_arr(), children_count_); }
1142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetIndexedReference(
1162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HeapGraphEdge::Type type, int index, HeapEntry* entry);
1172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetNamedReference(
1182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HeapGraphEdge::Type type, const char* name, HeapEntry* entry);
1192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Print(
1212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      const char* prefix, const char* edge_name, int max_depth, int indent);
1222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
1242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  INLINE(HeapGraphEdge** children_arr());
1252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* TypeAsString();
1262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned type_: 4;
1282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int children_count_: 28;
1292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int children_index_;
130f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  size_t self_size_;
1312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshot* snapshot_;
1322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* name_;
133ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  SnapshotObjectId id_;
134ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  // id of allocation stack trace top node
135ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  unsigned trace_node_id_;
1362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
1372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// HeapSnapshot represents a single heap snapshot. It is stored in
140ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org// HeapProfiler, which is also a factory for
1412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// HeapSnapshots. All HeapSnapshots share strings copied from JS heap
1422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// to be able to return them even if they were collected.
1432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// HeapSnapshotGenerator fills in a HeapSnapshot.
1442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapSnapshot {
1452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
146ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  HeapSnapshot(HeapProfiler* profiler,
1472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org               const char* title,
1482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org               unsigned uid);
1492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Delete();
1502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
151ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  HeapProfiler* profiler() { return profiler_; }
1522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* title() { return title_; }
1532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned uid() { return uid_; }
1542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  size_t RawSnapshotSize() const;
1552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* root() { return &entries_[root_index_]; }
1562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* gc_roots() { return &entries_[gc_roots_index_]; }
1572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* gc_subroot(int index) {
1582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return &entries_[gc_subroot_indexes_[index]];
1592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
1602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapEntry>& entries() { return entries_; }
1612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapGraphEdge>& edges() { return edges_; }
1622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapGraphEdge*>& children() { return children_; }
1632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void RememberLastJSObjectId();
1642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshotObjectId max_snapshot_js_object_id() const {
1652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return max_snapshot_js_object_id_;
1662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
1672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* AddEntry(HeapEntry::Type type,
1692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                      const char* name,
1702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                      SnapshotObjectId id,
171ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org                      size_t size,
172ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org                      unsigned trace_node_id);
17306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void AddSyntheticRootEntries();
1742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* GetEntryById(SnapshotObjectId id);
1752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapEntry*>* GetSortedEntriesList();
1762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void FillChildren();
1772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Print(int max_depth);
1792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void PrintEntriesSize();
1802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
18206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HeapEntry* AddRootEntry();
18306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HeapEntry* AddGcRootsEntry();
18406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HeapEntry* AddGcSubrootEntry(int tag, SnapshotObjectId id);
18506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
186ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  HeapProfiler* profiler_;
1872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* title_;
1882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned uid_;
1892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int root_index_;
1902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int gc_roots_index_;
1912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int gc_subroot_indexes_[VisitorSynchronization::kNumberOfSyncTags];
1922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapEntry> entries_;
1932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapGraphEdge> edges_;
1942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapGraphEdge*> children_;
1952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapEntry*> sorted_entries_;
1962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshotObjectId max_snapshot_js_object_id_;
1972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class HeapSnapshotTester;
1992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(HeapSnapshot);
2012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
2022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapObjectsMap {
2052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
2062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  explicit HeapObjectsMap(Heap* heap);
2072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Heap* heap() const { return heap_; }
2092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshotObjectId FindEntry(Address addr);
211a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  SnapshotObjectId FindOrAddEntry(Address addr,
212a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org                                  unsigned int size,
213a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org                                  bool accessed = true);
214ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  bool MoveObject(Address from, Address to, int size);
215a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void UpdateObjectSize(Address addr, int size);
2162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshotObjectId last_assigned_id() const {
2172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return next_id_ - kObjectIdStep;
2182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
2192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void StopHeapObjectsTracking();
2212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
2222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  size_t GetUsedMemorySize() const;
2232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
224ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info);
2252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const int kObjectIdStep = 2;
2272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const SnapshotObjectId kInternalRootObjectId;
2282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const SnapshotObjectId kGcRootsObjectId;
2292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const SnapshotObjectId kGcRootsFirstSubrootId;
2302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const SnapshotObjectId kFirstAvailableObjectId;
2312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
232a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  int FindUntrackedObjects();
233a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
234a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void UpdateHeapObjectsMap();
235ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  void RemoveDeadEntries();
236a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
2372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
2382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  struct EntryInfo {
2392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  EntryInfo(SnapshotObjectId id, Address addr, unsigned int size)
2402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      : id(id), addr(addr), size(size), accessed(true) { }
2412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  EntryInfo(SnapshotObjectId id, Address addr, unsigned int size, bool accessed)
2422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      : id(id), addr(addr), size(size), accessed(accessed) { }
2432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    SnapshotObjectId id;
2442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    Address addr;
2452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    unsigned int size;
2462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    bool accessed;
2472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
2482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  struct TimeInterval {
2492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    explicit TimeInterval(SnapshotObjectId id) : id(id), size(0), count(0) { }
2502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    SnapshotObjectId id;
2512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    uint32_t size;
2522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    uint32_t count;
2532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
2542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshotObjectId next_id_;
2562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HashMap entries_map_;
2572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<EntryInfo> entries_;
2582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<TimeInterval> time_intervals_;
2592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Heap* heap_;
2602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap);
2622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
2632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// A typedef for referencing anything that can be snapshotted living
2662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// in any kind of heap memory.
2672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgtypedef void* HeapThing;
2682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// An interface that creates HeapEntries by HeapThings.
2712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapEntriesAllocator {
2722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
2732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual ~HeapEntriesAllocator() { }
2742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0;
2752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
2762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// The HeapEntriesMap instance is used to track a mapping between
2792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// real heap objects and their representations in heap snapshots.
2802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapEntriesMap {
2812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
2822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntriesMap();
2832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int Map(HeapThing thing);
2852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Pair(HeapThing thing, int entry);
2862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
2882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static uint32_t Hash(HeapThing thing) {
2892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return ComputeIntegerHash(
2902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)),
2912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        v8::internal::kZeroHashSeed);
2922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
2932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HashMap entries_;
2952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class HeapObjectsSet;
2972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap);
2992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
3002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapObjectsSet {
3032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
3042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapObjectsSet();
3052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Clear();
3062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool Contains(Object* object);
3072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Insert(Object* obj);
3082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* GetTag(Object* obj);
3092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetTag(Object* obj, const char* tag);
3102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool is_empty() const { return entries_.occupancy() == 0; }
3112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
3132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HashMap entries_;
3142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet);
3162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
3172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass SnapshottingProgressReportingInterface {
3202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
3212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual ~SnapshottingProgressReportingInterface() { }
3222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual void ProgressStep() = 0;
3232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual bool ProgressReport(bool force) = 0;
3242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
3252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// An implementation of V8 heap graph extractor.
3282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass V8HeapExplorer : public HeapEntriesAllocator {
3292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
3302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  V8HeapExplorer(HeapSnapshot* snapshot,
3312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                 SnapshottingProgressReportingInterface* progress,
3322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                 v8::HeapProfiler::ObjectNameResolver* resolver);
3332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual ~V8HeapExplorer();
3342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual HeapEntry* AllocateEntry(HeapThing ptr);
335381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  void AddRootEntries(SnapshotFiller* filler);
3362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int EstimateObjectsCount(HeapIterator* iterator);
337381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  bool IterateAndExtractReferences(SnapshotFiller* filler);
3382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void TagGlobalObjects();
339057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  void TagCodeObject(Code* code);
34009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  void TagBuiltinCodeObject(Code* code, const char* name);
341f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HeapEntry* AddEntry(Address address,
342f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      HeapEntry::Type type,
343f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      const char* name,
344f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      size_t size);
3452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static String* GetConstructorName(JSObject* object);
3472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
3494edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  typedef bool (V8HeapExplorer::*ExtractReferencesMethod)(int entry,
3504edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org                                                          HeapObject* object);
3514edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
3522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* AddEntry(HeapObject* object);
3532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* AddEntry(HeapObject* object,
3542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                      HeapEntry::Type type,
3552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                      const char* name);
356f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* GetSystemEntryName(HeapObject* object);
3582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3594edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  template<V8HeapExplorer::ExtractReferencesMethod extractor>
3604edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  bool IterateAndExtractSinglePass();
3614edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
3624edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  bool ExtractReferencesPass1(int entry, HeapObject* obj);
3634edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  bool ExtractReferencesPass2(int entry, HeapObject* obj);
3641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void ExtractJSGlobalProxyReferences(int entry, JSGlobalProxy* proxy);
3652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractJSObjectReferences(int entry, JSObject* js_obj);
3662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractStringReferences(int entry, String* obj);
367fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  void ExtractSymbolReferences(int entry, Symbol* symbol);
36870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  void ExtractJSCollectionReferences(int entry, JSCollection* collection);
369011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  void ExtractJSWeakCollectionReferences(int entry,
370011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                                         JSWeakCollection* collection);
3712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractContextReferences(int entry, Context* context);
3722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractMapReferences(int entry, Map* map);
3732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractSharedFunctionInfoReferences(int entry,
3742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                           SharedFunctionInfo* shared);
3752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractScriptReferences(int entry, Script* script);
3766313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  void ExtractAccessorInfoReferences(int entry, AccessorInfo* accessor_info);
3771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void ExtractAccessorPairReferences(int entry, AccessorPair* accessors);
3782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractCodeCacheReferences(int entry, CodeCache* code_cache);
3792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractCodeReferences(int entry, Code* code);
3800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  void ExtractBoxReferences(int entry, Box* box);
38141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  void ExtractCellReferences(int entry, Cell* cell);
382b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  void ExtractPropertyCellReferences(int entry, PropertyCell* cell);
383bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  void ExtractAllocationSiteReferences(int entry, AllocationSite* site);
384f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void ExtractJSArrayBufferReferences(int entry, JSArrayBuffer* buffer);
3854edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  void ExtractFixedArrayReferences(int entry, FixedArray* array);
3862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractClosureReferences(JSObject* js_obj, int entry);
3872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractPropertyReferences(JSObject* js_obj, int entry);
3881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  bool ExtractAccessorPairProperty(JSObject* js_obj, int entry,
3891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                   Object* key, Object* callback_obj);
3902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractElementReferences(JSObject* js_obj, int entry);
3912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ExtractInternalReferences(JSObject* js_obj, int entry);
3924edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
3932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool IsEssentialObject(Object* object);
3942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  void SetContextReference(HeapObject* parent_obj,
3952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           int parent,
3962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           String* reference_name,
3972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                           Object* child,
3982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                           int field_offset);
3992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetNativeBindReference(HeapObject* parent_obj,
4002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                              int parent,
4012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                              const char* reference_name,
4022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                              Object* child);
4032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetElementReference(HeapObject* parent_obj,
4042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           int parent,
4052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           int index,
4062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           Object* child);
4072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetInternalReference(HeapObject* parent_obj,
4082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int parent,
4092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            const char* reference_name,
4102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            Object* child,
4112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int field_offset = -1);
4122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetInternalReference(HeapObject* parent_obj,
4132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int parent,
4142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int index,
4152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            Object* child,
4162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int field_offset = -1);
4172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetHiddenReference(HeapObject* parent_obj,
4182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                          int parent,
4192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                          int index,
4202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                          Object* child);
4212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetWeakReference(HeapObject* parent_obj,
4222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        int parent,
423af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org                        const char* reference_name,
4242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        Object* child_obj,
4252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        int field_offset);
4264edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  void SetWeakReference(HeapObject* parent_obj,
4274edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org                        int parent,
4284edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org                        int index,
4294edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org                        Object* child_obj,
4304edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org                        int field_offset);
4312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetPropertyReference(HeapObject* parent_obj,
4322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int parent,
433750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                            Name* reference_name,
4342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            Object* child,
4352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            const char* name_format_string = NULL,
4362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                            int field_offset = -1);
4372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetUserGlobalReference(Object* user_global);
4382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetRootGcRootsReference();
4392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
4402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetGcSubrootReference(
4412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      VisitorSynchronization::SyncTag tag, bool is_weak, Object* child);
4422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const char* GetStrongGcSubrootName(Object* object);
4432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void TagObject(Object* obj, const char* tag);
4444edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  void MarkAsWeakContainer(Object* object);
4452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntry* GetEntry(Object* obj);
4472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Heap* heap_;
4492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshot* snapshot_;
450ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  StringsStorage* names_;
451ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  HeapObjectsMap* heap_object_map_;
4522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshottingProgressReportingInterface* progress_;
453381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  SnapshotFiller* filler_;
4542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapObjectsSet objects_tags_;
4552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapObjectsSet strong_gc_subroot_names_;
4561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HeapObjectsSet user_roots_;
4574edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  HeapObjectsSet weak_containers_;
4582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_;
4592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class IndexedReferencesExtractor;
4612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class RootsReferencesExtractor;
4622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer);
4642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
4652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass NativeGroupRetainedObjectInfo;
4682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// An implementation of retained native objects extractor.
4712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass NativeObjectsExplorer {
4722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
4732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  NativeObjectsExplorer(HeapSnapshot* snapshot,
4743d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                        SnapshottingProgressReportingInterface* progress);
4752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual ~NativeObjectsExplorer();
476381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  void AddRootEntries(SnapshotFiller* filler);
4772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int EstimateObjectsCount();
478381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  bool IterateAndExtractReferences(SnapshotFiller* filler);
4792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
4812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void FillRetainedObjects();
4822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void FillImplicitReferences();
4832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  List<HeapObject*>* GetListMaybeDisposeInfo(v8::RetainedObjectInfo* info);
4842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetNativeRootReference(v8::RetainedObjectInfo* info);
4852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetRootNativeRootsReference();
4862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetWrapperNativeReferences(HeapObject* wrapper,
4872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                      v8::RetainedObjectInfo* info);
4882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void VisitSubtreeWrapper(Object** p, uint16_t class_id);
4892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static uint32_t InfoHash(v8::RetainedObjectInfo* info) {
4912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()),
4922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                              v8::internal::kZeroHashSeed);
4932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static bool RetainedInfosMatch(void* key1, void* key2) {
4952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return key1 == key2 ||
4962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        (reinterpret_cast<v8::RetainedObjectInfo*>(key1))->IsEquivalent(
4972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            reinterpret_cast<v8::RetainedObjectInfo*>(key2));
4982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  INLINE(static bool StringsMatch(void* key1, void* key2)) {
5002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return strcmp(reinterpret_cast<char*>(key1),
5012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                  reinterpret_cast<char*>(key2)) == 0;
5022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  NativeGroupRetainedObjectInfo* FindOrAddGroupInfo(const char* label);
5052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5063d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Isolate* isolate_;
5072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshot* snapshot_;
508ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  StringsStorage* names_;
5092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SnapshottingProgressReportingInterface* progress_;
5102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool embedder_queried_;
5112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapObjectsSet in_groups_;
5122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // RetainedObjectInfo* -> List<HeapObject*>*
5132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HashMap objects_by_info_;
5142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HashMap native_groups_;
5152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntriesAllocator* synthetic_entries_allocator_;
5162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntriesAllocator* native_entries_allocator_;
5172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Used during references extraction.
518381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  SnapshotFiller* filler_;
5192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static HeapThing const kNativesRootObject;
5212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class GlobalHandlesExtractor;
5232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer);
5252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
5262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
5292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
5302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshotGenerator(HeapSnapshot* snapshot,
5312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        v8::ActivityControl* control,
5322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        v8::HeapProfiler::ObjectNameResolver* resolver,
5332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        Heap* heap);
5342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool GenerateSnapshot();
5352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
5372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool FillReferences();
5382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void ProgressStep();
5392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool ProgressReport(bool force = false);
5402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SetProgressTotal(int iterations_count);
5412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshot* snapshot_;
5432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  v8::ActivityControl* control_;
5442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  V8HeapExplorer v8_heap_explorer_;
5452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  NativeObjectsExplorer dom_explorer_;
5462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Mapping from HeapThing pointers to HeapEntry* pointers.
5472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapEntriesMap entries_;
5482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Used during snapshot generation.
5492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int progress_counter_;
5502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int progress_total_;
5512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Heap* heap_;
5522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator);
5542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
5552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass OutputStreamWriter;
5572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass HeapSnapshotJSONSerializer {
5592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org public:
5602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot)
5612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      : snapshot_(snapshot),
562528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        strings_(StringsMatch),
5632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        next_node_id_(1),
5642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        next_string_id_(1),
5652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        writer_(NULL) {
5662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void Serialize(v8::OutputStream* stream);
5682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org private:
570528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  INLINE(static bool StringsMatch(void* key1, void* key2)) {
571528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return strcmp(reinterpret_cast<char*>(key1),
572528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                  reinterpret_cast<char*>(key2)) == 0;
5732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
575528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  INLINE(static uint32_t StringHash(const void* string)) {
576528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    const char* s = reinterpret_cast<const char*>(string);
577528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    int len = static_cast<int>(strlen(s));
578528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return StringHasher::HashSequentialString(
579528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        s, len, v8::internal::kZeroHashSeed);
5802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int GetStringId(const char* s);
5832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int entry_index(HeapEntry* e) { return e->index() * kNodeFieldsCount; }
5842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeEdge(HeapGraphEdge* edge, bool first_edge);
5852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeEdges();
5862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeImpl();
5872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeNode(HeapEntry* entry);
5882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeNodes();
5892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeSnapshot();
590b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  void SerializeTraceTree();
591b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  void SerializeTraceNode(AllocationTraceNode* node);
592b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  void SerializeTraceNodeInfos();
5932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeString(const unsigned char* s);
5942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void SerializeStrings();
5952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const int kEdgeFieldsCount;
5972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static const int kNodeFieldsCount;
5982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapSnapshot* snapshot_;
6002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HashMap strings_;
6012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int next_node_id_;
6022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int next_string_id_;
6032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  OutputStreamWriter* writer_;
6042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class HeapSnapshotJSONSerializerEnumerator;
6062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  friend class HeapSnapshotJSONSerializerIterator;
6072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer);
6092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
6102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org} }  // namespace v8::internal
6132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#endif  // V8_HEAP_SNAPSHOT_GENERATOR_H_
615