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