Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index 5d74c42ac1e0a6ec1310734bd5816a7203da29b6..ddc42f9763b774050c7d0e89f0118d96e0a1e282 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -1736,7 +1736,8 @@ V8HeapExplorer::V8HeapExplorer( |
snapshot_(snapshot), |
collection_(snapshot_->collection()), |
progress_(progress), |
- filler_(NULL) { |
+ filler_(NULL), |
+ gc_subroot_names_(HeapEntriesMap::HeapThingsMatch) { |
} |
@@ -2653,11 +2654,49 @@ void V8HeapExplorer::SetGcSubrootReference( |
VisitorSynchronization::SyncTag tag, bool is_weak, Object* child_obj) { |
HeapEntry* child_entry = GetEntry(child_obj); |
if (child_entry != NULL) { |
- filler_->SetIndexedAutoIndexReference( |
- is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement, |
- GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag), |
- child_obj, child_entry); |
- } |
+ const char* name = GetGcSubrootName(child_obj); |
+ if (name != NULL) { |
+ filler_->SetNamedReference( |
+ HeapGraphEdge::kInternal, |
+ GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag), |
+ name, |
+ child_obj, child_entry); |
+ } else { |
+ filler_->SetIndexedAutoIndexReference( |
+ is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement, |
+ GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag), |
+ child_obj, child_entry); |
+ } |
+ } |
+} |
+ |
+ |
+const char* V8HeapExplorer::GetGcSubrootName(Object* object) { |
+ if (gc_subroot_names_.occupancy() == 0) { |
+ HashMap::Entry* entry; |
+ Object* obj; |
+#define NAME_ENTRY(name) \ |
+ obj = heap_->name(); \ |
+ if (obj != NULL) { \ |
+ entry = gc_subroot_names_.Lookup(obj, HeapEntriesMap::Hash(obj), true); \ |
+ entry->value = const_cast<char*>(#name); \ |
+ } |
+#define ROOT_NAME(type, name, camel_name) NAME_ENTRY(name) |
+ STRONG_ROOT_LIST(ROOT_NAME) |
+#undef ROOT_NAME |
+#define STRUCT_MAP_NAME(NAME, Name, name) NAME_ENTRY(name##_map) |
+ STRUCT_LIST(STRUCT_MAP_NAME) |
+#undef STRUCT_MAP_NAME |
+#define SYMBOL_NAME(name, str) NAME_ENTRY(name) |
+ SYMBOL_LIST(SYMBOL_NAME) |
+#undef SYMBOL_NAME |
+#undef NAME_ENTRY |
+ CHECK(gc_subroot_names_.occupancy() > 0); |
+ CHECK(gc_subroot_names_.occupancy() <= Heap::kStrongRootListLength); |
+ } |
+ HashMap::Entry* entry = gc_subroot_names_.Lookup( |
+ object, HeapEntriesMap::Hash(object), false); |
+ return entry != NULL ? reinterpret_cast<const char*>(entry->value) : NULL; |
} |