Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index 97de08e5bf96b3703699731c70ee817d4aa3e944..194a40395a251faa92e0aaf138e2ff1c2983052f 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -1308,19 +1308,6 @@ HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag, |
} |
-HeapEntry* HeapSnapshot::AddNativesRootEntry(int children_count, |
- int retainers_count) { |
- ASSERT(natives_root_entry_ == NULL); |
- return (natives_root_entry_ = AddEntry( |
- HeapEntry::kObject, |
- "(Native objects)", |
- HeapObjectsMap::kNativesRootObjectId, |
- 0, |
- children_count, |
- retainers_count)); |
-} |
- |
- |
HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, |
const char* name, |
uint64_t id, |
@@ -1402,10 +1389,8 @@ void HeapSnapshot::Print(int max_depth) { |
const uint64_t HeapObjectsMap::kInternalRootObjectId = 1; |
const uint64_t HeapObjectsMap::kGcRootsObjectId = |
HeapObjectsMap::kInternalRootObjectId + HeapObjectsMap::kObjectIdStep; |
-const uint64_t HeapObjectsMap::kNativesRootObjectId = |
- HeapObjectsMap::kGcRootsObjectId + HeapObjectsMap::kObjectIdStep; |
const uint64_t HeapObjectsMap::kGcRootsFirstSubrootId = |
- HeapObjectsMap::kNativesRootObjectId + HeapObjectsMap::kObjectIdStep; |
+ HeapObjectsMap::kGcRootsObjectId + HeapObjectsMap::kObjectIdStep; |
const uint64_t HeapObjectsMap::kFirstAvailableObjectId = |
HeapObjectsMap::kGcRootsFirstSubrootId + |
VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep; |
@@ -2712,11 +2697,6 @@ class GlobalHandlesExtractor : public ObjectVisitor { |
NativeObjectsExplorer* explorer_; |
}; |
-HeapThing const NativeObjectsExplorer::kNativesRootObject = |
- reinterpret_cast<HeapThing>( |
- static_cast<intptr_t>(HeapObjectsMap::kNativesRootObjectId)); |
- |
- |
NativeObjectsExplorer::NativeObjectsExplorer( |
HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress) |
: snapshot_(snapshot), |
@@ -2724,6 +2704,7 @@ NativeObjectsExplorer::NativeObjectsExplorer( |
progress_(progress), |
embedder_queried_(false), |
objects_by_info_(RetainedInfosMatch), |
+ native_groups_(StringsMatch), |
filler_(NULL) { |
} |
@@ -2744,32 +2725,22 @@ NativeObjectsExplorer::~NativeObjectsExplorer() { |
HeapEntry* NativeObjectsExplorer::AllocateEntry( |
HeapThing ptr, int children_count, int retainers_count) { |
- if (ptr == kNativesRootObject) { |
- return snapshot_->AddNativesRootEntry(children_count, retainers_count); |
- } else { |
- v8::RetainedObjectInfo* info = |
- reinterpret_cast<v8::RetainedObjectInfo*>(ptr); |
- intptr_t elements = info->GetElementCount(); |
- intptr_t size = info->GetSizeInBytes(); |
- return snapshot_->AddEntry( |
- HeapEntry::kNative, |
- elements != -1 ? |
- collection_->names()->GetFormatted( |
- "%s / %" V8_PTR_PREFIX "d entries", |
- info->GetLabel(), |
- info->GetElementCount()) : |
- collection_->names()->GetCopy(info->GetLabel()), |
- HeapObjectsMap::GenerateId(info), |
- size != -1 ? static_cast<int>(size) : 0, |
- children_count, |
- retainers_count); |
- } |
-} |
- |
- |
-void NativeObjectsExplorer::AddRootEntries(SnapshotFillerInterface* filler) { |
- if (EstimateObjectsCount() <= 0) return; |
- filler->AddEntry(kNativesRootObject, this); |
+ v8::RetainedObjectInfo* info = |
+ reinterpret_cast<v8::RetainedObjectInfo*>(ptr); |
+ intptr_t elements = info->GetElementCount(); |
+ intptr_t size = info->GetSizeInBytes(); |
+ return snapshot_->AddEntry( |
+ HeapEntry::kNative, |
+ elements != -1 ? |
+ collection_->names()->GetFormatted( |
+ "%s / %" V8_PTR_PREFIX "d entries", |
+ info->GetLabel(), |
+ info->GetElementCount()) : |
+ collection_->names()->GetCopy(info->GetLabel()), |
+ HeapObjectsMap::GenerateId(info), |
+ size != -1 ? static_cast<int>(size) : 0, |
+ children_count, |
+ retainers_count); |
} |
@@ -2835,19 +2806,61 @@ bool NativeObjectsExplorer::IterateAndExtractReferences( |
SetWrapperNativeReferences(objects->at(i), info); |
} |
} |
- SetRootNativesRootReference(); |
+ SetRootNativeRootsReference(); |
filler_ = NULL; |
return true; |
} |
+class NativeGroupRetainedObjectInfo : public v8::RetainedObjectInfo { |
+ public: |
+ explicit NativeGroupRetainedObjectInfo(const char* label) |
+ : disposed_(false), |
+ hash_(reinterpret_cast<intptr_t>(label)), |
+ label_(label) { |
+ } |
+ |
+ virtual ~NativeGroupRetainedObjectInfo() {} |
+ virtual void Dispose() { |
+ CHECK(!disposed_); |
+ disposed_ = true; |
+ } |
+ virtual bool IsEquivalent(RetainedObjectInfo* other) { |
+ return hash_ == other->GetHash() && !strcmp(label_, other->GetLabel()); |
+ } |
+ virtual intptr_t GetHash() { return hash_; } |
+ virtual const char* GetLabel() { return label_; } |
+ |
+ private: |
+ bool disposed_; |
+ int hash_; |
+ const char* label_; |
+}; |
+ |
+ |
+NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( |
+ const char* label) { |
+ const char* label_copy = collection_->names()->GetCopy(label); |
+ intptr_t hash = HashSequentialString(label_copy, strlen(label_copy), |
+ HEAP->HashSeed()); |
+ HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy), |
+ hash, true); |
+ if (entry->value == NULL) |
+ entry->value = new NativeGroupRetainedObjectInfo(label); |
+ return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); |
+} |
+ |
+ |
void NativeObjectsExplorer::SetNativeRootReference( |
v8::RetainedObjectInfo* info) { |
HeapEntry* child_entry = filler_->FindOrAddEntry(info, this); |
ASSERT(child_entry != NULL); |
- filler_->SetIndexedAutoIndexReference( |
- HeapGraphEdge::kElement, |
- kNativesRootObject, snapshot_->natives_root(), |
+ NativeGroupRetainedObjectInfo* group_info = |
+ FindOrAddGroupInfo(info->GetGroupLabel()); |
+ HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this); |
+ filler_->SetNamedAutoIndexReference( |
+ HeapGraphEdge::kInternal, |
+ group_info, group_entry, |
info, child_entry); |
} |
@@ -2868,11 +2881,19 @@ void NativeObjectsExplorer::SetWrapperNativeReferences( |
} |
-void NativeObjectsExplorer::SetRootNativesRootReference() { |
- filler_->SetIndexedAutoIndexReference( |
- HeapGraphEdge::kElement, |
- V8HeapExplorer::kInternalRootObject, snapshot_->root(), |
- kNativesRootObject, snapshot_->natives_root()); |
+void NativeObjectsExplorer::SetRootNativeRootsReference() { |
+ for (HashMap::Entry* entry = native_groups_.Start(); |
+ entry; |
+ entry = native_groups_.Next(entry)) { |
+ NativeGroupRetainedObjectInfo* group_info = |
+ static_cast<NativeGroupRetainedObjectInfo*>(entry->value); |
+ HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this); |
+ ASSERT(group_entry != NULL); |
+ filler_->SetIndexedAutoIndexReference( |
+ HeapGraphEdge::kElement, |
+ V8HeapExplorer::kInternalRootObject, snapshot_->root(), |
+ group_info, group_entry); |
+ } |
} |
@@ -3107,7 +3128,6 @@ void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { |
bool HeapSnapshotGenerator::CountEntriesAndReferences() { |
SnapshotCounter counter(&entries_); |
v8_heap_explorer_.AddRootEntries(&counter); |
- dom_explorer_.AddRootEntries(&counter); |
return |
v8_heap_explorer_.IterateAndExtractReferences(&counter) && |
dom_explorer_.IterateAndExtractReferences(&counter); |