Commit f5e65cc8 authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

Revert "[heap profiler] Refactor: remove SnapshotFiller proxy"

This reverts commit 0352ea97.

Reason for revert: A dependent patch broke the build https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Linux%20gcc%204.8/22123

Original change's description:
> [heap profiler] Refactor: remove SnapshotFiller proxy
> 
> Long time ago there were two passes over heap. One was counting
> objects and edge and another was filling them. Since then we have
> just a single pass, but the filler object is still there.
> 
> Remove it for the sake of layering simplicity.
> 
> Change-Id: Ic873eb5ca616b9dcae17fe388197dde8f539026f
> Reviewed-on: https://chromium-review.googlesource.com/1244380
> Commit-Queue: Alexei Filippov <alph@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56246}

TBR=ulan@chromium.org,alph@chromium.org,mlippautz@chromium.org

Change-Id: If71ddcc0008d138054074fc4cca3f38e032763e0
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/1246234Reviewed-by: 's avatarAlexei Filippov <alph@chromium.org>
Commit-Queue: Alexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56247}
parent 0352ea97
...@@ -82,17 +82,6 @@ void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type, ...@@ -82,17 +82,6 @@ void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type,
snapshot_->edges().emplace_back(type, index, this, entry); snapshot_->edges().emplace_back(type, index, this, entry);
} }
void HeapEntry::SetNamedAutoIndexReference(HeapGraphEdge::Type type,
const char* description,
HeapEntry* child,
StringsStorage* names) {
int index = children_count_ + 1;
const char* name = description
? names->GetFormatted("%d / %s", index, description)
: names->GetName(index);
SetNamedReference(type, name, child);
}
void HeapEntry::Print( void HeapEntry::Print(
const char* prefix, const char* edge_name, int max_depth, int indent) { const char* prefix, const char* edge_name, int max_depth, int indent) {
STATIC_ASSERT(sizeof(unsigned) == sizeof(id())); STATIC_ASSERT(sizeof(unsigned) == sizeof(id()));
...@@ -152,6 +141,7 @@ void HeapEntry::Print( ...@@ -152,6 +141,7 @@ void HeapEntry::Print(
} }
} }
const char* HeapEntry::TypeAsString() { const char* HeapEntry::TypeAsString() {
switch (type()) { switch (type()) {
case kHidden: return "/hidden/"; case kHidden: return "/hidden/";
...@@ -506,7 +496,7 @@ V8HeapExplorer::V8HeapExplorer(HeapSnapshot* snapshot, ...@@ -506,7 +496,7 @@ V8HeapExplorer::V8HeapExplorer(HeapSnapshot* snapshot,
names_(snapshot_->profiler()->names()), names_(snapshot_->profiler()->names()),
heap_object_map_(snapshot_->profiler()->heap_object_map()), heap_object_map_(snapshot_->profiler()->heap_object_map()),
progress_(progress), progress_(progress),
generator_(nullptr), filler_(nullptr),
global_object_name_resolver_(resolver) {} global_object_name_resolver_(resolver) {}
HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) { HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) {
...@@ -567,14 +557,17 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { ...@@ -567,14 +557,17 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
return AddEntry(object, HeapEntry::kObject, name); return AddEntry(object, HeapEntry::kObject, name);
} else if (object->IsString()) { } else if (object->IsString()) {
String* string = String::cast(object); String* string = String::cast(object);
if (string->IsConsString()) { if (string->IsConsString())
return AddEntry(object, HeapEntry::kConsString, "(concatenated string)"); return AddEntry(object,
} else if (string->IsSlicedString()) { HeapEntry::kConsString,
return AddEntry(object, HeapEntry::kSlicedString, "(sliced string)"); "(concatenated string)");
} else { if (string->IsSlicedString())
return AddEntry(object, HeapEntry::kString, return AddEntry(object,
names_->GetName(String::cast(object))); HeapEntry::kSlicedString,
} "(sliced string)");
return AddEntry(object,
HeapEntry::kString,
names_->GetName(String::cast(object)));
} else if (object->IsSymbol()) { } else if (object->IsSymbol()) {
if (Symbol::cast(object)->is_private()) if (Symbol::cast(object)->is_private())
return AddEntry(object, HeapEntry::kHidden, "private symbol"); return AddEntry(object, HeapEntry::kHidden, "private symbol");
...@@ -586,12 +579,16 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { ...@@ -586,12 +579,16 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
return AddEntry(object, HeapEntry::kCode, ""); return AddEntry(object, HeapEntry::kCode, "");
} else if (object->IsSharedFunctionInfo()) { } else if (object->IsSharedFunctionInfo()) {
String* name = SharedFunctionInfo::cast(object)->Name(); String* name = SharedFunctionInfo::cast(object)->Name();
return AddEntry(object, HeapEntry::kCode, names_->GetName(name)); return AddEntry(object,
HeapEntry::kCode,
names_->GetName(name));
} else if (object->IsScript()) { } else if (object->IsScript()) {
Object* name = Script::cast(object)->name(); Object* name = Script::cast(object)->name();
return AddEntry( return AddEntry(object,
object, HeapEntry::kCode, HeapEntry::kCode,
name->IsString() ? names_->GetName(String::cast(name)) : ""); name->IsString()
? names_->GetName(String::cast(name))
: "");
} else if (object->IsNativeContext()) { } else if (object->IsNativeContext()) {
return AddEntry(object, HeapEntry::kHidden, "system / NativeContext"); return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
} else if (object->IsContext()) { } else if (object->IsContext()) {
...@@ -605,12 +602,14 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { ...@@ -605,12 +602,14 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object)); return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object));
} }
HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
HeapEntry::Type type, HeapEntry::Type type,
const char* name) { const char* name) {
return AddEntry(object->address(), type, name, object->Size()); return AddEntry(object->address(), type, name, object->Size());
} }
HeapEntry* V8HeapExplorer::AddEntry(Address address, HeapEntry* V8HeapExplorer::AddEntry(Address address,
HeapEntry::Type type, HeapEntry::Type type,
const char* name, const char* name,
...@@ -626,6 +625,57 @@ HeapEntry* V8HeapExplorer::AddEntry(Address address, ...@@ -626,6 +625,57 @@ HeapEntry* V8HeapExplorer::AddEntry(Address address,
return snapshot_->AddEntry(type, name, object_id, size, trace_node_id); return snapshot_->AddEntry(type, name, object_id, size, trace_node_id);
} }
class SnapshotFiller {
public:
SnapshotFiller(HeapSnapshot* snapshot,
HeapSnapshotGenerator::HeapEntriesMap* entries_map)
: names_(snapshot->profiler()->names()), entries_map_(entries_map) {}
HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
return entries_map_->emplace(ptr, allocator->AllocateEntry(ptr))
.first->second;
}
HeapEntry* FindEntry(HeapThing ptr) {
auto it = entries_map_->find(ptr);
return it != entries_map_->end() ? it->second : nullptr;
}
HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
HeapEntry* entry = FindEntry(ptr);
return entry != nullptr ? entry : AddEntry(ptr, allocator);
}
void SetIndexedReference(HeapGraphEdge::Type type, HeapEntry* parent,
int index, HeapEntry* child) {
parent->SetIndexedReference(type, index, child);
}
void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, HeapEntry* parent,
HeapEntry* child) {
int index = parent->children_count() + 1;
parent->SetIndexedReference(type, index, child);
}
void SetNamedReference(HeapGraphEdge::Type type, HeapEntry* parent,
const char* reference_name, HeapEntry* child) {
parent->SetNamedReference(type, reference_name, child);
}
void SetNamedAutoIndexReference(HeapGraphEdge::Type type, HeapEntry* parent,
const char* description, HeapEntry* child) {
int index = parent->children_count() + 1;
const char* name = description
? names_->GetFormatted("%d / %s", index, description)
: names_->GetName(index);
parent->SetNamedReference(type, name, child);
}
private:
StringsStorage* names_;
HeapSnapshotGenerator::HeapEntriesMap* entries_map_;
};
const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) {
switch (object->map()->instance_type()) { switch (object->map()->instance_type()) {
case MAP_TYPE: case MAP_TYPE:
...@@ -911,8 +961,8 @@ void V8HeapExplorer::ExtractEphemeronHashTableReferences( ...@@ -911,8 +961,8 @@ void V8HeapExplorer::ExtractEphemeronHashTableReferences(
if (key_entry && value_entry) { if (key_entry && value_entry) {
const char* edge_name = const char* edge_name =
names_->GetFormatted("key %s in WeakMap", key_entry->name()); names_->GetFormatted("key %s in WeakMap", key_entry->name());
key_entry->SetNamedAutoIndexReference(HeapGraphEdge::kInternal, edge_name, filler_->SetNamedAutoIndexReference(HeapGraphEdge::kInternal, key_entry,
value_entry, names_); edge_name, value_entry);
} }
} }
} }
...@@ -1194,9 +1244,9 @@ void V8HeapExplorer::ExtractJSArrayBufferReferences(HeapEntry* entry, ...@@ -1194,9 +1244,9 @@ void V8HeapExplorer::ExtractJSArrayBufferReferences(HeapEntry* entry,
size_t data_size = buffer->byte_length(); size_t data_size = buffer->byte_length();
JSArrayBufferDataEntryAllocator allocator(data_size, this); JSArrayBufferDataEntryAllocator allocator(data_size, this);
HeapEntry* data_entry = HeapEntry* data_entry =
generator_->FindOrAddEntry(buffer->backing_store(), &allocator); filler_->FindOrAddEntry(buffer->backing_store(), &allocator);
entry->SetNamedReference(HeapGraphEdge::kInternal, "backing_store", filler_->SetNamedReference(HeapGraphEdge::kInternal,
data_entry); entry, "backing_store", data_entry);
} }
void V8HeapExplorer::ExtractJSPromiseReferences(HeapEntry* entry, void V8HeapExplorer::ExtractJSPromiseReferences(HeapEntry* entry,
...@@ -1392,7 +1442,8 @@ String* V8HeapExplorer::GetConstructorName(JSObject* object) { ...@@ -1392,7 +1442,8 @@ String* V8HeapExplorer::GetConstructorName(JSObject* object) {
HeapEntry* V8HeapExplorer::GetEntry(Object* obj) { HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
return obj->IsHeapObject() ? generator_->FindOrAddEntry(obj, this) : nullptr; if (!obj->IsHeapObject()) return nullptr;
return filler_->FindOrAddEntry(obj, this);
} }
class RootsReferencesExtractor : public RootVisitor { class RootsReferencesExtractor : public RootVisitor {
...@@ -1422,9 +1473,8 @@ class RootsReferencesExtractor : public RootVisitor { ...@@ -1422,9 +1473,8 @@ class RootsReferencesExtractor : public RootVisitor {
bool visiting_weak_roots_; bool visiting_weak_roots_;
}; };
bool V8HeapExplorer::IterateAndExtractReferences( bool V8HeapExplorer::IterateAndExtractReferences(SnapshotFiller* filler) {
HeapSnapshotGenerator* generator) { filler_ = filler;
generator_ = generator;
// Create references to the synthetic roots. // Create references to the synthetic roots.
SetRootGcRootsReference(); SetRootGcRootsReference();
...@@ -1475,7 +1525,7 @@ bool V8HeapExplorer::IterateAndExtractReferences( ...@@ -1475,7 +1525,7 @@ bool V8HeapExplorer::IterateAndExtractReferences(
if (!progress_->ProgressReport(false)) interrupted = true; if (!progress_->ProgressReport(false)) interrupted = true;
} }
generator_ = nullptr; filler_ = nullptr;
return interrupted ? false : progress_->ProgressReport(true); return interrupted ? false : progress_->ProgressReport(true);
} }
...@@ -1516,8 +1566,8 @@ void V8HeapExplorer::SetContextReference(HeapObject* parent_obj, ...@@ -1516,8 +1566,8 @@ void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
DCHECK_EQ(parent_entry, GetEntry(parent_obj)); DCHECK_EQ(parent_entry, GetEntry(parent_obj));
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
parent_entry->SetNamedReference(HeapGraphEdge::kContextVariable, filler_->SetNamedReference(HeapGraphEdge::kContextVariable, parent_entry,
names_->GetName(reference_name), child_entry); names_->GetName(reference_name), child_entry);
MarkVisitedField(field_offset); MarkVisitedField(field_offset);
} }
...@@ -1535,8 +1585,8 @@ void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, ...@@ -1535,8 +1585,8 @@ void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
DCHECK_EQ(parent_entry, GetEntry(parent_obj)); DCHECK_EQ(parent_entry, GetEntry(parent_obj));
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
parent_entry->SetNamedReference(HeapGraphEdge::kShortcut, reference_name, filler_->SetNamedReference(HeapGraphEdge::kShortcut, parent_entry,
child_entry); reference_name, child_entry);
} }
void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
...@@ -1545,8 +1595,8 @@ void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, ...@@ -1545,8 +1595,8 @@ void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
DCHECK_EQ(parent_entry, GetEntry(parent_obj)); DCHECK_EQ(parent_entry, GetEntry(parent_obj));
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
parent_entry->SetIndexedReference(HeapGraphEdge::kElement, index, filler_->SetIndexedReference(HeapGraphEdge::kElement, parent_entry, index,
child_entry); child_entry);
} }
void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
...@@ -1557,8 +1607,10 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, ...@@ -1557,8 +1607,10 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
if (IsEssentialObject(child_obj)) { if (IsEssentialObject(child_obj)) {
parent_entry->SetNamedReference(HeapGraphEdge::kInternal, reference_name, filler_->SetNamedReference(HeapGraphEdge::kInternal,
child_entry); parent_entry,
reference_name,
child_entry);
} }
MarkVisitedField(field_offset); MarkVisitedField(field_offset);
} }
...@@ -1570,8 +1622,10 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, ...@@ -1570,8 +1622,10 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
if (IsEssentialObject(child_obj)) { if (IsEssentialObject(child_obj)) {
parent_entry->SetNamedReference(HeapGraphEdge::kInternal, filler_->SetNamedReference(HeapGraphEdge::kInternal,
names_->GetName(index), child_entry); parent_entry,
names_->GetName(index),
child_entry);
} }
MarkVisitedField(field_offset); MarkVisitedField(field_offset);
} }
...@@ -1583,8 +1637,8 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, ...@@ -1583,8 +1637,8 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != nullptr && IsEssentialObject(child_obj) && if (child_entry != nullptr && IsEssentialObject(child_obj) &&
IsEssentialHiddenReference(parent_obj, field_offset)) { IsEssentialHiddenReference(parent_obj, field_offset)) {
parent_entry->SetIndexedReference(HeapGraphEdge::kHidden, index, filler_->SetIndexedReference(HeapGraphEdge::kHidden, parent_entry, index,
child_entry); child_entry);
} }
} }
...@@ -1596,8 +1650,10 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, ...@@ -1596,8 +1650,10 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
if (IsEssentialObject(child_obj)) { if (IsEssentialObject(child_obj)) {
parent_entry->SetNamedReference(HeapGraphEdge::kWeak, reference_name, filler_->SetNamedReference(HeapGraphEdge::kWeak,
child_entry); parent_entry,
reference_name,
child_entry);
} }
MarkVisitedField(field_offset); MarkVisitedField(field_offset);
} }
...@@ -1609,8 +1665,10 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, ...@@ -1609,8 +1665,10 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return; if (child_entry == nullptr) return;
if (IsEssentialObject(child_obj)) { if (IsEssentialObject(child_obj)) {
parent_entry->SetNamedReference( filler_->SetNamedReference(HeapGraphEdge::kWeak,
HeapGraphEdge::kWeak, names_->GetFormatted("%d", index), child_entry); parent_entry,
names_->GetFormatted("%d", index),
child_entry);
} }
MarkVisitedField(field_offset); MarkVisitedField(field_offset);
} }
...@@ -1648,25 +1706,26 @@ void V8HeapExplorer::SetPropertyReference( ...@@ -1648,25 +1706,26 @@ void V8HeapExplorer::SetPropertyReference(
.get()) .get())
: names_->GetName(reference_name); : names_->GetName(reference_name);
parent_entry->SetNamedReference(type, name, child_entry); filler_->SetNamedReference(type, parent_entry, name, child_entry);
MarkVisitedField(field_offset); MarkVisitedField(field_offset);
} }
void V8HeapExplorer::SetRootGcRootsReference() { void V8HeapExplorer::SetRootGcRootsReference() {
snapshot_->root()->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, filler_->SetIndexedAutoIndexReference(
snapshot_->gc_roots()); HeapGraphEdge::kElement, snapshot_->root(), snapshot_->gc_roots());
} }
void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) { void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
DCHECK_NOT_NULL(child_entry); DCHECK_NOT_NULL(child_entry);
snapshot_->root()->SetNamedAutoIndexReference(HeapGraphEdge::kShortcut, filler_->SetNamedAutoIndexReference(HeapGraphEdge::kShortcut,
nullptr, child_entry, names_); snapshot_->root(), nullptr, child_entry);
} }
void V8HeapExplorer::SetGcRootsReference(Root root) { void V8HeapExplorer::SetGcRootsReference(Root root) {
snapshot_->gc_roots()->SetIndexedAutoIndexReference( filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
HeapGraphEdge::kElement, snapshot_->gc_subroot(root)); snapshot_->gc_roots(),
snapshot_->gc_subroot(root));
} }
void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description, void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description,
...@@ -1677,11 +1736,11 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description, ...@@ -1677,11 +1736,11 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description,
HeapGraphEdge::Type edge_type = HeapGraphEdge::Type edge_type =
is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kInternal; is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kInternal;
if (name != nullptr) { if (name != nullptr) {
snapshot_->gc_subroot(root)->SetNamedReference(edge_type, name, filler_->SetNamedReference(edge_type, snapshot_->gc_subroot(root), name,
child_entry); child_entry);
} else { } else {
snapshot_->gc_subroot(root)->SetNamedAutoIndexReference( filler_->SetNamedAutoIndexReference(edge_type, snapshot_->gc_subroot(root),
edge_type, description, child_entry, names_); description, child_entry);
} }
// Add a shortcut to JS global object reference at snapshot root. // Add a shortcut to JS global object reference at snapshot root.
...@@ -1958,7 +2017,8 @@ NativeObjectsExplorer::NativeObjectsExplorer( ...@@ -1958,7 +2017,8 @@ NativeObjectsExplorer::NativeObjectsExplorer(
native_entries_allocator_( native_entries_allocator_(
new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative)), new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative)),
embedder_graph_entries_allocator_( embedder_graph_entries_allocator_(
new EmbedderGraphEntriesAllocator(snapshot)) {} new EmbedderGraphEntriesAllocator(snapshot)),
filler_(nullptr) {}
NativeObjectsExplorer::~NativeObjectsExplorer() { NativeObjectsExplorer::~NativeObjectsExplorer() {
for (auto map_entry : objects_by_info_) { for (auto map_entry : objects_by_info_) {
...@@ -2017,15 +2077,15 @@ void NativeObjectsExplorer::FillEdges() { ...@@ -2017,15 +2077,15 @@ void NativeObjectsExplorer::FillEdges() {
*pair.first->Get(reinterpret_cast<v8::Isolate*>(isolate_))); *pair.first->Get(reinterpret_cast<v8::Isolate*>(isolate_)));
HeapObject* parent = HeapObject::cast(*parent_object); HeapObject* parent = HeapObject::cast(*parent_object);
HeapEntry* parent_entry = HeapEntry* parent_entry =
generator_->FindOrAddEntry(parent, native_entries_allocator_.get()); filler_->FindOrAddEntry(parent, native_entries_allocator_.get());
DCHECK_NOT_NULL(parent_entry); DCHECK_NOT_NULL(parent_entry);
Handle<Object> child_object = v8::Utils::OpenHandle( Handle<Object> child_object = v8::Utils::OpenHandle(
*pair.second->Get(reinterpret_cast<v8::Isolate*>(isolate_))); *pair.second->Get(reinterpret_cast<v8::Isolate*>(isolate_)));
HeapObject* child = HeapObject::cast(*child_object); HeapObject* child = HeapObject::cast(*child_object);
HeapEntry* child_entry = HeapEntry* child_entry =
generator_->FindOrAddEntry(child, native_entries_allocator_.get()); filler_->FindOrAddEntry(child, native_entries_allocator_.get());
parent_entry->SetNamedReference(HeapGraphEdge::kInternal, "native", filler_->SetNamedReference(HeapGraphEdge::kInternal, parent_entry, "native",
child_entry); child_entry);
} }
edges_.clear(); edges_.clear();
} }
...@@ -2047,20 +2107,20 @@ HeapEntry* NativeObjectsExplorer::EntryForEmbedderGraphNode( ...@@ -2047,20 +2107,20 @@ HeapEntry* NativeObjectsExplorer::EntryForEmbedderGraphNode(
node = wrapper; node = wrapper;
} }
if (node->IsEmbedderNode()) { if (node->IsEmbedderNode()) {
return generator_->FindOrAddEntry(node, return filler_->FindOrAddEntry(node,
embedder_graph_entries_allocator_.get()); embedder_graph_entries_allocator_.get());
} else { } else {
EmbedderGraphImpl::V8NodeImpl* v8_node = EmbedderGraphImpl::V8NodeImpl* v8_node =
static_cast<EmbedderGraphImpl::V8NodeImpl*>(node); static_cast<EmbedderGraphImpl::V8NodeImpl*>(node);
Object* object = v8_node->GetObject(); Object* object = v8_node->GetObject();
if (object->IsSmi()) return nullptr; if (object->IsSmi()) return nullptr;
return generator_->FindEntry(HeapObject::cast(object)); return filler_->FindEntry(HeapObject::cast(object));
} }
} }
bool NativeObjectsExplorer::IterateAndExtractReferences( bool NativeObjectsExplorer::IterateAndExtractReferences(
HeapSnapshotGenerator* generator) { SnapshotFiller* filler) {
generator_ = generator; filler_ = filler;
if (FLAG_heap_profiler_use_embedder_graph && if (FLAG_heap_profiler_use_embedder_graph &&
snapshot_->profiler()->HasBuildEmbedderGraphCallback()) { snapshot_->profiler()->HasBuildEmbedderGraphCallback()) {
...@@ -2070,8 +2130,9 @@ bool NativeObjectsExplorer::IterateAndExtractReferences( ...@@ -2070,8 +2130,9 @@ bool NativeObjectsExplorer::IterateAndExtractReferences(
snapshot_->profiler()->BuildEmbedderGraph(isolate_, &graph); snapshot_->profiler()->BuildEmbedderGraph(isolate_, &graph);
for (const auto& node : graph.nodes()) { for (const auto& node : graph.nodes()) {
if (node->IsRootNode()) { if (node->IsRootNode()) {
snapshot_->root()->SetIndexedAutoIndexReference( filler_->SetIndexedAutoIndexReference(
HeapGraphEdge::kElement, EntryForEmbedderGraphNode(node.get())); HeapGraphEdge::kElement, snapshot_->root(),
EntryForEmbedderGraphNode(node.get()));
} }
// Adjust the name and the type of the V8 wrapper node. // Adjust the name and the type of the V8 wrapper node.
auto wrapper = node->WrapperNode(); auto wrapper = node->WrapperNode();
...@@ -2086,15 +2147,18 @@ bool NativeObjectsExplorer::IterateAndExtractReferences( ...@@ -2086,15 +2147,18 @@ bool NativeObjectsExplorer::IterateAndExtractReferences(
// Fill edges of the graph. // Fill edges of the graph.
for (const auto& edge : graph.edges()) { for (const auto& edge : graph.edges()) {
HeapEntry* from = EntryForEmbedderGraphNode(edge.from); HeapEntry* from = EntryForEmbedderGraphNode(edge.from);
// |from| and |to| can be nullptr if the corresponding node is a V8 node // The |from| and |to| can nullptr if the corrsponding node is a V8 node
// pointing to a Smi. // pointing to a Smi.
if (!from) continue; if (!from) continue;
HeapEntry* to = EntryForEmbedderGraphNode(edge.to); HeapEntry* to = EntryForEmbedderGraphNode(edge.to);
if (!to) continue; if (to) {
if (edge.name == nullptr) { if (edge.name == nullptr) {
from->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, to); filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, from,
} else { to);
from->SetNamedReference(HeapGraphEdge::kInternal, edge.name, to); } else {
filler_->SetNamedReference(HeapGraphEdge::kInternal, from, edge.name,
to);
}
} }
} }
} else { } else {
...@@ -2112,7 +2176,7 @@ bool NativeObjectsExplorer::IterateAndExtractReferences( ...@@ -2112,7 +2176,7 @@ bool NativeObjectsExplorer::IterateAndExtractReferences(
SetRootNativeRootsReference(); SetRootNativeRootsReference();
} }
} }
generator_ = nullptr; filler_ = nullptr;
return true; return true;
} }
...@@ -2128,37 +2192,39 @@ NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( ...@@ -2128,37 +2192,39 @@ NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo(
void NativeObjectsExplorer::SetNativeRootReference( void NativeObjectsExplorer::SetNativeRootReference(
v8::RetainedObjectInfo* info) { v8::RetainedObjectInfo* info) {
HeapEntry* child_entry = HeapEntry* child_entry =
generator_->FindOrAddEntry(info, native_entries_allocator_.get()); filler_->FindOrAddEntry(info, native_entries_allocator_.get());
DCHECK_NOT_NULL(child_entry); DCHECK_NOT_NULL(child_entry);
NativeGroupRetainedObjectInfo* group_info = NativeGroupRetainedObjectInfo* group_info =
FindOrAddGroupInfo(info->GetGroupLabel()); FindOrAddGroupInfo(info->GetGroupLabel());
HeapEntry* group_entry = generator_->FindOrAddEntry( HeapEntry* group_entry =
group_info, synthetic_entries_allocator_.get()); filler_->FindOrAddEntry(group_info, synthetic_entries_allocator_.get());
group_entry->SetNamedAutoIndexReference(HeapGraphEdge::kInternal, nullptr, filler_->SetNamedAutoIndexReference(HeapGraphEdge::kInternal, group_entry,
child_entry, names_); nullptr, child_entry);
} }
void NativeObjectsExplorer::SetWrapperNativeReferences( void NativeObjectsExplorer::SetWrapperNativeReferences(
HeapObject* wrapper, v8::RetainedObjectInfo* info) { HeapObject* wrapper, v8::RetainedObjectInfo* info) {
HeapEntry* wrapper_entry = generator_->FindEntry(wrapper); HeapEntry* wrapper_entry = filler_->FindEntry(wrapper);
DCHECK_NOT_NULL(wrapper_entry); DCHECK_NOT_NULL(wrapper_entry);
HeapEntry* info_entry = HeapEntry* info_entry =
generator_->FindOrAddEntry(info, native_entries_allocator_.get()); filler_->FindOrAddEntry(info, native_entries_allocator_.get());
DCHECK_NOT_NULL(info_entry); DCHECK_NOT_NULL(info_entry);
wrapper_entry->SetNamedReference(HeapGraphEdge::kInternal, "native", filler_->SetNamedReference(HeapGraphEdge::kInternal, wrapper_entry, "native",
info_entry); info_entry);
info_entry->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, info_entry,
wrapper_entry); wrapper_entry);
} }
void NativeObjectsExplorer::SetRootNativeRootsReference() { void NativeObjectsExplorer::SetRootNativeRootsReference() {
for (auto map_entry : native_groups_) { for (auto map_entry : native_groups_) {
NativeGroupRetainedObjectInfo* group_info = map_entry.second; NativeGroupRetainedObjectInfo* group_info = map_entry.second;
HeapEntry* group_entry = HeapEntry* group_entry =
generator_->FindOrAddEntry(group_info, native_entries_allocator_.get()); filler_->FindOrAddEntry(group_info, native_entries_allocator_.get());
DCHECK_NOT_NULL(group_entry); DCHECK_NOT_NULL(group_entry);
snapshot_->root()->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
group_entry); snapshot_->root(), group_entry);
} }
} }
...@@ -2265,10 +2331,12 @@ void HeapSnapshotGenerator::InitProgressCounter() { ...@@ -2265,10 +2331,12 @@ void HeapSnapshotGenerator::InitProgressCounter() {
} }
bool HeapSnapshotGenerator::FillReferences() { bool HeapSnapshotGenerator::FillReferences() {
return v8_heap_explorer_.IterateAndExtractReferences(this) && SnapshotFiller filler(snapshot_, &entries_map_);
dom_explorer_.IterateAndExtractReferences(this); return v8_heap_explorer_.IterateAndExtractReferences(&filler) &&
dom_explorer_.IterateAndExtractReferences(&filler);
} }
template<int bytes> struct MaxDecimalDigitsIn; template<int bytes> struct MaxDecimalDigitsIn;
template<> struct MaxDecimalDigitsIn<4> { template<> struct MaxDecimalDigitsIn<4> {
static const int kSigned = 11; static const int kSigned = 11;
...@@ -2279,6 +2347,7 @@ template<> struct MaxDecimalDigitsIn<8> { ...@@ -2279,6 +2347,7 @@ template<> struct MaxDecimalDigitsIn<8> {
static const int kUnsigned = 20; static const int kUnsigned = 20;
}; };
class OutputStreamWriter { class OutputStreamWriter {
public: public:
explicit OutputStreamWriter(v8::OutputStream* stream) explicit OutputStreamWriter(v8::OutputStream* stream)
......
...@@ -29,7 +29,6 @@ class HeapEntry; ...@@ -29,7 +29,6 @@ class HeapEntry;
class HeapIterator; class HeapIterator;
class HeapProfiler; class HeapProfiler;
class HeapSnapshot; class HeapSnapshot;
class HeapSnapshotGenerator;
class JSArrayBuffer; class JSArrayBuffer;
class JSCollection; class JSCollection;
class JSGeneratorObject; class JSGeneratorObject;
...@@ -37,6 +36,7 @@ class JSGlobalObject; ...@@ -37,6 +36,7 @@ class JSGlobalObject;
class JSGlobalProxy; class JSGlobalProxy;
class JSPromise; class JSPromise;
class JSWeakCollection; class JSWeakCollection;
class SnapshotFiller;
struct SourceLocation { struct SourceLocation {
SourceLocation(int entry_index, int scriptId, int line, int col) SourceLocation(int entry_index, int scriptId, int line, int col)
...@@ -136,13 +136,6 @@ class HeapEntry { ...@@ -136,13 +136,6 @@ class HeapEntry {
HeapGraphEdge::Type type, int index, HeapEntry* entry); HeapGraphEdge::Type type, int index, HeapEntry* entry);
void SetNamedReference( void SetNamedReference(
HeapGraphEdge::Type type, const char* name, HeapEntry* entry); HeapGraphEdge::Type type, const char* name, HeapEntry* entry);
void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
HeapEntry* child) {
SetIndexedReference(type, children_count_ + 1, child);
}
void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
const char* description, HeapEntry* child,
StringsStorage* strings);
void Print( void Print(
const char* prefix, const char* edge_name, int max_depth, int indent); const char* prefix, const char* edge_name, int max_depth, int indent);
...@@ -317,10 +310,9 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -317,10 +310,9 @@ class V8HeapExplorer : public HeapEntriesAllocator {
SnapshottingProgressReportingInterface* progress, SnapshottingProgressReportingInterface* progress,
v8::HeapProfiler::ObjectNameResolver* resolver); v8::HeapProfiler::ObjectNameResolver* resolver);
~V8HeapExplorer() override = default; ~V8HeapExplorer() override = default;
HeapEntry* AllocateEntry(HeapThing ptr) override; HeapEntry* AllocateEntry(HeapThing ptr) override;
int EstimateObjectsCount(); int EstimateObjectsCount();
bool IterateAndExtractReferences(HeapSnapshotGenerator* generator); bool IterateAndExtractReferences(SnapshotFiller* filler);
void TagGlobalObjects(); void TagGlobalObjects();
void TagCodeObject(Code* code); void TagCodeObject(Code* code);
void TagBuiltinCodeObject(Code* code, const char* name); void TagBuiltinCodeObject(Code* code, const char* name);
...@@ -433,7 +425,7 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -433,7 +425,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
StringsStorage* names_; StringsStorage* names_;
HeapObjectsMap* heap_object_map_; HeapObjectsMap* heap_object_map_;
SnapshottingProgressReportingInterface* progress_; SnapshottingProgressReportingInterface* progress_;
HeapSnapshotGenerator* generator_ = nullptr; SnapshotFiller* filler_;
std::unordered_map<JSGlobalObject*, const char*> objects_tags_; std::unordered_map<JSGlobalObject*, const char*> objects_tags_;
std::unordered_map<Object*, const char*> strong_gc_subroot_names_; std::unordered_map<Object*, const char*> strong_gc_subroot_names_;
std::unordered_set<JSGlobalObject*> user_roots_; std::unordered_set<JSGlobalObject*> user_roots_;
...@@ -458,7 +450,7 @@ class NativeObjectsExplorer { ...@@ -458,7 +450,7 @@ class NativeObjectsExplorer {
SnapshottingProgressReportingInterface* progress); SnapshottingProgressReportingInterface* progress);
virtual ~NativeObjectsExplorer(); virtual ~NativeObjectsExplorer();
int EstimateObjectsCount(); int EstimateObjectsCount();
bool IterateAndExtractReferences(HeapSnapshotGenerator* generator); bool IterateAndExtractReferences(SnapshotFiller* filler);
private: private:
void FillRetainedObjects(); void FillRetainedObjects();
...@@ -502,7 +494,7 @@ class NativeObjectsExplorer { ...@@ -502,7 +494,7 @@ class NativeObjectsExplorer {
std::unique_ptr<HeapEntriesAllocator> native_entries_allocator_; std::unique_ptr<HeapEntriesAllocator> native_entries_allocator_;
std::unique_ptr<HeapEntriesAllocator> embedder_graph_entries_allocator_; std::unique_ptr<HeapEntriesAllocator> embedder_graph_entries_allocator_;
// Used during references extraction. // Used during references extraction.
HeapSnapshotGenerator* generator_ = nullptr; SnapshotFiller* filler_;
v8::HeapProfiler::RetainerEdges edges_; v8::HeapProfiler::RetainerEdges edges_;
static HeapThing const kNativesRootObject; static HeapThing const kNativesRootObject;
...@@ -512,6 +504,7 @@ class NativeObjectsExplorer { ...@@ -512,6 +504,7 @@ class NativeObjectsExplorer {
DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer); DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer);
}; };
class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
public: public:
// The HeapEntriesMap instance is used to track a mapping between // The HeapEntriesMap instance is used to track a mapping between
...@@ -524,21 +517,6 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { ...@@ -524,21 +517,6 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
Heap* heap); Heap* heap);
bool GenerateSnapshot(); bool GenerateSnapshot();
HeapEntry* FindEntry(HeapThing ptr) {
auto it = entries_map_.find(ptr);
return it != entries_map_.end() ? it->second : nullptr;
}
HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
return entries_map_.emplace(ptr, allocator->AllocateEntry(ptr))
.first->second;
}
HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
HeapEntry* entry = FindEntry(ptr);
return entry != nullptr ? entry : AddEntry(ptr, allocator);
}
private: private:
bool FillReferences(); bool FillReferences();
void ProgressStep() override; void ProgressStep() override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment