| 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;
|
| }
|
|
|
|
|
|
|