Index: src/profile-generator.h |
diff --git a/src/profile-generator.h b/src/profile-generator.h |
index e04ddbf3e277dd3b1b2710ad25e109e343310bee..18c157cdfd88be9d96bec203e3ec4d318db049fb 100644 |
--- a/src/profile-generator.h |
+++ b/src/profile-generator.h |
@@ -446,6 +446,7 @@ class ProfileGenerator { |
class HeapEntry; |
+class HeapSnapshot; |
class HeapGraphEdge BASE_EMBEDDED { |
public: |
@@ -460,9 +461,9 @@ class HeapGraphEdge BASE_EMBEDDED { |
}; |
HeapGraphEdge() { } |
- void Init(int child_index, Type type, const char* name, HeapEntry* to); |
- void Init(int child_index, Type type, int index, HeapEntry* to); |
- void Init(int child_index, int index, HeapEntry* to); |
+ HeapGraphEdge(Type type, const char* name, int from, int to); |
+ HeapGraphEdge(Type type, int index, int from, int to); |
+ void ReplaceToIndexWithEntry(HeapSnapshot* snapshot); |
Type type() const { return static_cast<Type>(type_); } |
int index() const { |
@@ -471,48 +472,34 @@ class HeapGraphEdge BASE_EMBEDDED { |
} |
const char* name() const { |
ASSERT(type_ == kContextVariable |
- || type_ == kProperty |
- || type_ == kInternal |
- || type_ == kShortcut); |
+ || type_ == kProperty |
+ || type_ == kInternal |
+ || type_ == kShortcut); |
return name_; |
} |
- HeapEntry* to() const { return to_; } |
INLINE(HeapEntry* from() const); |
+ HeapEntry* to() const { return to_entry_; } |
private: |
- int child_index_ : 29; |
+ INLINE(HeapSnapshot* snapshot() const); |
+ |
unsigned type_ : 3; |
+ int from_index_ : 29; |
+ union { |
+ // During entries population |to_index_| is used for storing the index, |
+ // afterwards it is replaced with a pointer to the entry. |
+ int to_index_; |
+ HeapEntry* to_entry_; |
+ }; |
union { |
int index_; |
const char* name_; |
}; |
- HeapEntry* to_; |
- |
- DISALLOW_COPY_AND_ASSIGN(HeapGraphEdge); |
}; |
-class HeapSnapshot; |
- |
// HeapEntry instances represent an entity from the heap (or a special |
-// virtual node, e.g. root). To make heap snapshots more compact, |
-// HeapEntries has a special memory layout (no Vectors or Lists used): |
-// |
-// +-----------------+ |
-// HeapEntry |
-// +-----------------+ |
-// HeapGraphEdge | |
-// ... } children_count |
-// HeapGraphEdge | |
-// +-----------------+ |
-// HeapGraphEdge* | |
-// ... } retainers_count |
-// HeapGraphEdge* | |
-// +-----------------+ |
-// |
-// In a HeapSnapshot, all entries are hand-allocated in a continuous array |
-// of raw bytes. |
-// |
+// virtual node, e.g. root). |
class HeapEntry BASE_EMBEDDED { |
public: |
enum Type { |
@@ -527,15 +514,14 @@ class HeapEntry BASE_EMBEDDED { |
kNative = v8::HeapGraphNode::kNative, |
kSynthetic = v8::HeapGraphNode::kSynthetic |
}; |
+ static const int kNoEntry; |
HeapEntry() { } |
- void Init(HeapSnapshot* snapshot, |
+ HeapEntry(HeapSnapshot* snapshot, |
Type type, |
const char* name, |
SnapshotObjectId id, |
- int self_size, |
- int children_count, |
- int retainers_count); |
+ int self_size); |
HeapSnapshot* snapshot() { return snapshot_; } |
Type type() { return static_cast<Type>(type_); } |
@@ -545,20 +531,27 @@ class HeapEntry BASE_EMBEDDED { |
int self_size() { return self_size_; } |
int retained_size() { return retained_size_; } |
void add_retained_size(int size) { retained_size_ += size; } |
- void set_retained_size(int value) { retained_size_ = value; } |
- int ordered_index() { return ordered_index_; } |
- void set_ordered_index(int value) { ordered_index_ = value; } |
- int entry_index() { return entry_index_; } |
- void set_entry_index(int value) { entry_index_ = value; } |
- |
- Vector<HeapGraphEdge> children() { |
- return Vector<HeapGraphEdge>(children_arr(), children_count_); } |
+ void set_retained_size(int size) { retained_size_ = size; } |
+ INLINE(int index() const); |
+ int postorder_index() { return postorder_index_; } |
+ void set_postorder_index(int value) { postorder_index_ = value; } |
+ int children_count() const { return children_count_; } |
+ INLINE(int set_children_index(int index)); |
+ INLINE(int set_retainers_index(int index)); |
+ void add_child(HeapGraphEdge* edge) { |
+ children_arr()[children_count_++] = edge; |
+ } |
+ void add_retainer(HeapGraphEdge* edge) { |
+ retainers_arr()[retainers_count_++] = edge; |
+ } |
+ Vector<HeapGraphEdge*> children() { |
+ return Vector<HeapGraphEdge*>(children_arr(), children_count_); } |
Vector<HeapGraphEdge*> retainers() { |
return Vector<HeapGraphEdge*>(retainers_arr(), retainers_count_); } |
- HeapEntry* dominator() { return dominator_; } |
+ INLINE(HeapEntry* dominator() const); |
void set_dominator(HeapEntry* entry) { |
ASSERT(entry != NULL); |
- dominator_ = entry; |
+ dominator_ = entry->index(); |
} |
void clear_paint() { painted_ = false; } |
bool painted() { return painted_; } |
@@ -566,57 +559,37 @@ class HeapEntry BASE_EMBEDDED { |
bool user_reachable() { return user_reachable_; } |
void set_user_reachable() { user_reachable_ = true; } |
- void SetIndexedReference(HeapGraphEdge::Type type, |
- int child_index, |
- int index, |
- HeapEntry* entry, |
- int retainer_index); |
- void SetNamedReference(HeapGraphEdge::Type type, |
- int child_index, |
- const char* name, |
- HeapEntry* entry, |
- int retainer_index); |
- void SetUnidirElementReference(int child_index, int index, HeapEntry* entry); |
- |
- size_t EntrySize() { |
- return EntriesSize(1, children_count_, retainers_count_); |
- } |
+ void SetIndexedReference( |
+ HeapGraphEdge::Type type, int index, HeapEntry* entry); |
+ void SetNamedReference( |
+ HeapGraphEdge::Type type, const char* name, HeapEntry* entry); |
void Print( |
const char* prefix, const char* edge_name, int max_depth, int indent); |
Handle<HeapObject> GetHeapObject(); |
- static size_t EntriesSize(int entries_count, |
- int children_count, |
- int retainers_count); |
- |
private: |
- HeapGraphEdge* children_arr() { |
- return reinterpret_cast<HeapGraphEdge*>(this + 1); |
- } |
- HeapGraphEdge** retainers_arr() { |
- return reinterpret_cast<HeapGraphEdge**>(children_arr() + children_count_); |
- } |
+ INLINE(HeapGraphEdge** children_arr()); |
+ INLINE(HeapGraphEdge** retainers_arr()); |
const char* TypeAsString(); |
unsigned painted_: 1; |
unsigned user_reachable_: 1; |
+ int dominator_: 30; |
unsigned type_: 4; |
- int children_count_: 26; |
- int retainers_count_; |
+ int retainers_count_: 28; |
+ int retainers_index_; |
+ int children_count_; |
+ int children_index_; |
int self_size_; |
union { |
- int ordered_index_; // Used during dominator tree building. |
- int retained_size_; // At that moment, there is no retained size yet. |
+ int postorder_index_; // Used during dominator tree building. |
+ int retained_size_; // At that moment, there is no retained size yet. |
}; |
- int entry_index_; |
SnapshotObjectId id_; |
- HeapEntry* dominator_; |
HeapSnapshot* snapshot_; |
const char* name_; |
- |
- DISALLOW_COPY_AND_ASSIGN(HeapEntry); |
}; |
@@ -637,63 +610,59 @@ class HeapSnapshot { |
Type type, |
const char* title, |
unsigned uid); |
- ~HeapSnapshot(); |
void Delete(); |
HeapSnapshotsCollection* collection() { return collection_; } |
Type type() { return type_; } |
const char* title() { return title_; } |
unsigned uid() { return uid_; } |
- HeapEntry* root() { return root_entry_; } |
- HeapEntry* gc_roots() { return gc_roots_entry_; } |
- HeapEntry* natives_root() { return natives_root_entry_; } |
- HeapEntry* gc_subroot(int index) { return gc_subroot_entries_[index]; } |
- List<HeapEntry*>* entries() { return &entries_; } |
- size_t raw_entries_size() { return raw_entries_size_; } |
- int number_of_edges() { return number_of_edges_; } |
+ size_t RawSnapshotSize() const; |
+ HeapEntry* root() { return &entries_[root_index_]; } |
+ HeapEntry* gc_roots() { return &entries_[gc_roots_index_]; } |
+ HeapEntry* natives_root() { return &entries_[natives_root_index_]; } |
+ HeapEntry* gc_subroot(int index) { |
+ return &entries_[gc_subroot_indexes_[index]]; |
+ } |
+ List<HeapEntry>& entries() { return entries_; } |
+ List<HeapGraphEdge>& edges() { return edges_; } |
+ List<HeapGraphEdge*>& children() { return children_; } |
+ List<HeapGraphEdge*>& retainers() { return retainers_; } |
void RememberLastJSObjectId(); |
SnapshotObjectId max_snapshot_js_object_id() const { |
return max_snapshot_js_object_id_; |
} |
- void AllocateEntries( |
- int entries_count, int children_count, int retainers_count); |
HeapEntry* AddEntry(HeapEntry::Type type, |
const char* name, |
SnapshotObjectId id, |
- int size, |
- int children_count, |
- int retainers_count); |
- HeapEntry* AddRootEntry(int children_count); |
- HeapEntry* AddGcRootsEntry(int children_count, int retainers_count); |
- HeapEntry* AddGcSubrootEntry(int tag, |
- int children_count, |
- int retainers_count); |
- HeapEntry* AddNativesRootEntry(int children_count, int retainers_count); |
+ int size); |
+ HeapEntry* AddRootEntry(); |
+ HeapEntry* AddGcRootsEntry(); |
+ HeapEntry* AddGcSubrootEntry(int tag); |
+ HeapEntry* AddNativesRootEntry(); |
void ClearPaint(); |
HeapEntry* GetEntryById(SnapshotObjectId id); |
List<HeapEntry*>* GetSortedEntriesList(); |
void SetDominatorsToSelf(); |
+ void FillChildrenAndRetainers(); |
void Print(int max_depth); |
void PrintEntriesSize(); |
private: |
- HeapEntry* GetNextEntryToInit(); |
- |
HeapSnapshotsCollection* collection_; |
Type type_; |
const char* title_; |
unsigned uid_; |
- HeapEntry* root_entry_; |
- HeapEntry* gc_roots_entry_; |
- HeapEntry* natives_root_entry_; |
- HeapEntry* gc_subroot_entries_[VisitorSynchronization::kNumberOfSyncTags]; |
- char* raw_entries_; |
- List<HeapEntry*> entries_; |
+ int root_index_; |
+ int gc_roots_index_; |
+ int natives_root_index_; |
+ int gc_subroot_indexes_[VisitorSynchronization::kNumberOfSyncTags]; |
+ List<HeapEntry> entries_; |
+ List<HeapGraphEdge> edges_; |
+ List<HeapGraphEdge*> children_; |
+ List<HeapGraphEdge*> retainers_; |
List<HeapEntry*> sorted_entries_; |
- size_t raw_entries_size_; |
- int number_of_edges_; |
SnapshotObjectId max_snapshot_js_object_id_; |
friend class HeapSnapshotTester; |
@@ -828,8 +797,7 @@ typedef void* HeapThing; |
class HeapEntriesAllocator { |
public: |
virtual ~HeapEntriesAllocator() { } |
- virtual HeapEntry* AllocateEntry( |
- HeapThing ptr, int children_count, int retainers_count) = 0; |
+ virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0; |
}; |
@@ -838,37 +806,11 @@ class HeapEntriesAllocator { |
class HeapEntriesMap { |
public: |
HeapEntriesMap(); |
- ~HeapEntriesMap(); |
- |
- void AllocateEntries(HeapThing root_object); |
- HeapEntry* Map(HeapThing thing); |
- void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry); |
- void CountReference(HeapThing from, HeapThing to, |
- int* prev_children_count = NULL, |
- int* prev_retainers_count = NULL); |
- int entries_count() { return entries_count_; } |
- int total_children_count() { return total_children_count_; } |
- int total_retainers_count() { return total_retainers_count_; } |
- |
- static HeapEntry* const kHeapEntryPlaceholder; |
+ int Map(HeapThing thing); |
+ void Pair(HeapThing thing, int entry); |
private: |
- struct EntryInfo { |
- EntryInfo(HeapEntry* entry, HeapEntriesAllocator* allocator) |
- : entry(entry), |
- allocator(allocator), |
- children_count(0), |
- retainers_count(0) { |
- } |
- HeapEntry* entry; |
- HeapEntriesAllocator* allocator; |
- int children_count; |
- int retainers_count; |
- }; |
- |
- static inline void AllocateHeapEntryForMapEntry(HashMap::Entry* map_entry); |
- |
static uint32_t Hash(HeapThing thing) { |
return ComputeIntegerHash( |
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)), |
@@ -879,9 +821,6 @@ class HeapEntriesMap { |
} |
HashMap entries_; |
- int entries_count_; |
- int total_children_count_; |
- int total_retainers_count_; |
friend class HeapObjectsSet; |
@@ -916,26 +855,18 @@ class SnapshotFillerInterface { |
virtual HeapEntry* FindOrAddEntry(HeapThing ptr, |
HeapEntriesAllocator* allocator) = 0; |
virtual void SetIndexedReference(HeapGraphEdge::Type type, |
- HeapThing parent_ptr, |
- HeapEntry* parent_entry, |
+ int parent_entry, |
int index, |
- HeapThing child_ptr, |
HeapEntry* child_entry) = 0; |
virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, |
- HeapThing parent_ptr, |
- HeapEntry* parent_entry, |
- HeapThing child_ptr, |
+ int parent_entry, |
HeapEntry* child_entry) = 0; |
virtual void SetNamedReference(HeapGraphEdge::Type type, |
- HeapThing parent_ptr, |
- HeapEntry* parent_entry, |
+ int parent_entry, |
const char* reference_name, |
- HeapThing child_ptr, |
HeapEntry* child_entry) = 0; |
virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type, |
- HeapThing parent_ptr, |
- HeapEntry* parent_entry, |
- HeapThing child_ptr, |
+ int parent_entry, |
HeapEntry* child_entry) = 0; |
}; |
@@ -954,8 +885,7 @@ class V8HeapExplorer : public HeapEntriesAllocator { |
V8HeapExplorer(HeapSnapshot* snapshot, |
SnapshottingProgressReportingInterface* progress); |
virtual ~V8HeapExplorer(); |
- virtual HeapEntry* AllocateEntry( |
- HeapThing ptr, int children_count, int retainers_count); |
+ virtual HeapEntry* AllocateEntry(HeapThing ptr); |
void AddRootEntries(SnapshotFillerInterface* filler); |
int EstimateObjectsCount(HeapIterator* iterator); |
bool IterateAndExtractReferences(SnapshotFillerInterface* filler); |
@@ -967,75 +897,72 @@ class V8HeapExplorer : public HeapEntriesAllocator { |
static HeapObject* const kInternalRootObject; |
private: |
- HeapEntry* AddEntry( |
- HeapObject* object, int children_count, int retainers_count); |
+ HeapEntry* AddEntry(HeapObject* object); |
HeapEntry* AddEntry(HeapObject* object, |
HeapEntry::Type type, |
- const char* name, |
- int children_count, |
- int retainers_count); |
+ const char* name); |
const char* GetSystemEntryName(HeapObject* object); |
void ExtractReferences(HeapObject* obj); |
void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy); |
- void ExtractJSObjectReferences(HeapEntry* entry, JSObject* js_obj); |
- void ExtractStringReferences(HeapEntry* entry, String* obj); |
- void ExtractContextReferences(HeapEntry* entry, Context* context); |
- void ExtractMapReferences(HeapEntry* entry, Map* map); |
- void ExtractSharedFunctionInfoReferences(HeapEntry* entry, |
+ void ExtractJSObjectReferences(int entry, JSObject* js_obj); |
+ void ExtractStringReferences(int entry, String* obj); |
+ void ExtractContextReferences(int entry, Context* context); |
+ void ExtractMapReferences(int entry, Map* map); |
+ void ExtractSharedFunctionInfoReferences(int entry, |
SharedFunctionInfo* shared); |
- void ExtractScriptReferences(HeapEntry* entry, Script* script); |
- void ExtractCodeCacheReferences(HeapEntry* entry, CodeCache* code_cache); |
- void ExtractCodeReferences(HeapEntry* entry, Code* code); |
- void ExtractJSGlobalPropertyCellReferences(HeapEntry* entry, |
+ void ExtractScriptReferences(int entry, Script* script); |
+ void ExtractCodeCacheReferences(int entry, CodeCache* code_cache); |
+ void ExtractCodeReferences(int entry, Code* code); |
+ void ExtractJSGlobalPropertyCellReferences(int entry, |
JSGlobalPropertyCell* cell); |
- void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); |
- void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); |
- void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); |
- void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); |
+ void ExtractClosureReferences(JSObject* js_obj, int entry); |
+ void ExtractPropertyReferences(JSObject* js_obj, int entry); |
+ void ExtractElementReferences(JSObject* js_obj, int entry); |
+ void ExtractInternalReferences(JSObject* js_obj, int entry); |
bool IsEssentialObject(Object* object); |
void SetClosureReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
String* reference_name, |
Object* child); |
void SetNativeBindReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
const char* reference_name, |
Object* child); |
void SetElementReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
int index, |
Object* child); |
void SetInternalReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
const char* reference_name, |
Object* child, |
int field_offset = -1); |
void SetInternalReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
int index, |
Object* child, |
int field_offset = -1); |
void SetHiddenReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
int index, |
Object* child); |
void SetWeakReference(HeapObject* parent_obj, |
- HeapEntry* parent_entry, |
+ int parent, |
int index, |
Object* child_obj, |
int field_offset); |
void SetPropertyReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
String* reference_name, |
Object* child, |
const char* name_format_string = NULL, |
int field_offset = -1); |
void SetPropertyShortcutReference(HeapObject* parent_obj, |
- HeapEntry* parent, |
+ int parent, |
String* reference_name, |
Object* child); |
- void SetUserGlobalReference(Object* window); |
+ void SetUserGlobalReference(Object* user_global); |
void SetRootGcRootsReference(); |
void SetGcRootsReference(VisitorSynchronization::SyncTag tag); |
void SetGcSubrootReference( |
@@ -1139,10 +1066,9 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { |
bool BuildDominatorTree(const Vector<HeapEntry*>& entries, |
Vector<int>* dominators); |
bool CalculateRetainedSizes(); |
- bool CountEntriesAndReferences(); |
bool FillReferences(); |
void FillPostorderIndexes(Vector<HeapEntry*>* entries); |
- bool IsUserGlobalReference(const HeapGraphEdge& edge); |
+ bool IsUserGlobalReference(const HeapGraphEdge* edge); |
void MarkUserReachableObjects(); |
void ProgressStep(); |
bool ProgressReport(bool force = false); |
@@ -1186,20 +1112,21 @@ class HeapSnapshotJSONSerializer { |
v8::internal::kZeroHashSeed); |
} |
- void CalculateNodeIndexes(const List<HeapEntry*>& nodes); |
HeapSnapshot* CreateFakeSnapshot(); |
int GetStringId(const char* s); |
+ int entry_index(HeapEntry* e) { return e->index() * kNodeFieldsCount; } |
void SerializeEdge(HeapGraphEdge* edge, bool first_edge); |
- void SerializeEdges(const List<HeapEntry*>& nodes); |
+ void SerializeEdges(const List<HeapEntry>& nodes); |
void SerializeImpl(); |
void SerializeNode(HeapEntry* entry, int edges_index); |
- void SerializeNodes(const List<HeapEntry*>& nodes); |
+ void SerializeNodes(const List<HeapEntry>& nodes); |
void SerializeSnapshot(); |
void SerializeString(const unsigned char* s); |
void SerializeStrings(); |
void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries); |
- static const int kMaxSerializableSnapshotRawSize; |
+ static const int kEdgeFieldsCount; |
+ static const int kNodeFieldsCount; |
HeapSnapshot* snapshot_; |
HashMap strings_; |