Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: src/profile-generator.cc

Issue 6596073: Refactor heap profiler's code to make possible including (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/profile-generator.cc
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 261b3d6ff019c64f50a321dd841c9fef023ed1c6..8fa35cc2e4a18fc84684a44df389cf9f9b427462 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -1177,12 +1177,6 @@ void HeapGraphPath::Print() {
}
-HeapObject *const HeapSnapshot::kInternalRootObject =
- reinterpret_cast<HeapObject*>(1);
-HeapObject *const HeapSnapshot::kGcRootsObject =
- reinterpret_cast<HeapObject*>(2);
-
-
// It is very important to keep objects that form a heap snapshot
// as small as possible.
namespace { // Avoid littering the global namespace.
@@ -1253,96 +1247,6 @@ void HeapSnapshot::AllocateEntries(int entries_count,
}
-HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
- int children_count,
- int retainers_count) {
- if (object == kInternalRootObject) {
- ASSERT(root_entry_ == NULL);
- ASSERT(retainers_count == 0);
- return (root_entry_ = AddEntry(HeapEntry::kObject,
- "",
- HeapObjectsMap::kInternalRootObjectId,
- 0,
- children_count,
- retainers_count));
- } else if (object == kGcRootsObject) {
- ASSERT(gc_roots_entry_ == NULL);
- return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
- "(GC roots)",
- HeapObjectsMap::kGcRootsObjectId,
- 0,
- children_count,
- retainers_count));
- } else if (object->IsJSFunction()) {
- JSFunction* func = JSFunction::cast(object);
- SharedFunctionInfo* shared = func->shared();
- return AddEntry(object,
- HeapEntry::kClosure,
- collection_->GetName(String::cast(shared->name())),
- children_count,
- retainers_count);
- } else if (object->IsJSRegExp()) {
- JSRegExp* re = JSRegExp::cast(object);
- return AddEntry(object,
- HeapEntry::kRegExp,
- collection_->GetName(re->Pattern()),
- children_count,
- retainers_count);
- } else if (object->IsJSObject()) {
- return AddEntry(object,
- HeapEntry::kObject,
- collection_->GetName(GetConstructorNameForHeapProfile(
- JSObject::cast(object))),
- children_count,
- retainers_count);
- } else if (object->IsString()) {
- return AddEntry(object,
- HeapEntry::kString,
- collection_->GetName(String::cast(object)),
- children_count,
- retainers_count);
- } else if (object->IsCode()) {
- return AddEntry(object,
- HeapEntry::kCode,
- "",
- children_count,
- retainers_count);
- } else if (object->IsSharedFunctionInfo()) {
- SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
- return AddEntry(object,
- HeapEntry::kCode,
- collection_->GetName(String::cast(shared->name())),
- children_count,
- retainers_count);
- } else if (object->IsScript()) {
- Script* script = Script::cast(object);
- return AddEntry(object,
- HeapEntry::kCode,
- script->name()->IsString() ?
- collection_->GetName(String::cast(script->name())) : "",
- children_count,
- retainers_count);
- } else if (object->IsFixedArray()) {
- return AddEntry(object,
- HeapEntry::kArray,
- "",
- children_count,
- retainers_count);
- } else if (object->IsHeapNumber()) {
- return AddEntry(object,
- HeapEntry::kHeapNumber,
- "number",
- children_count,
- retainers_count);
- }
- return AddEntry(object,
- HeapEntry::kHidden,
- "system",
- children_count,
- retainers_count);
-}
-
-
static void HeapEntryClearPaint(HeapEntry** entry_ptr) {
(*entry_ptr)->clear_paint();
}
@@ -1352,17 +1256,26 @@ void HeapSnapshot::ClearPaint() {
}
-HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
- HeapEntry::Type type,
- const char* name,
- int children_count,
- int retainers_count) {
- return AddEntry(type,
- name,
- collection_->GetObjectId(object->address()),
- object->Size(),
- children_count,
- retainers_count);
+HeapEntry* HeapSnapshot::AddRootEntry(int children_count) {
+ ASSERT(root_entry_ == NULL);
+ return (root_entry_ = AddEntry(HeapEntry::kObject,
+ "",
+ HeapObjectsMap::kInternalRootObjectId,
+ 0,
+ children_count,
+ 0));
+}
+
+
+HeapEntry* HeapSnapshot::AddGcRootsEntry(int children_count,
+ int retainers_count) {
+ ASSERT(gc_roots_entry_ == NULL);
+ return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
+ "(GC roots)",
+ HeapObjectsMap::kGcRootsObjectId,
+ 0,
+ children_count,
+ retainers_count));
}
@@ -1615,7 +1528,7 @@ HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder =
reinterpret_cast<HeapEntry*>(1);
HeapEntriesMap::HeapEntriesMap()
- : entries_(HeapObjectsMatch),
+ : entries_(HeapThingsMatch),
entries_count_(0),
total_children_count_(0),
total_retainers_count_(0) {
@@ -1629,8 +1542,8 @@ HeapEntriesMap::~HeapEntriesMap() {
}
-HeapEntry* HeapEntriesMap::Map(HeapObject* object) {
- HashMap::Entry* cache_entry = entries_.Lookup(object, Hash(object), false);
+HeapEntry* HeapEntriesMap::Map(HeapThing thing) {
+ HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
if (cache_entry != NULL) {
EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value);
return entry_info->entry;
@@ -1640,15 +1553,16 @@ HeapEntry* HeapEntriesMap::Map(HeapObject* object) {
}
-void HeapEntriesMap::Pair(HeapObject* object, HeapEntry* entry) {
- HashMap::Entry* cache_entry = entries_.Lookup(object, Hash(object), true);
+void HeapEntriesMap::Pair(
+ HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry) {
+ HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true);
ASSERT(cache_entry->value == NULL);
- cache_entry->value = new EntryInfo(entry);
+ cache_entry->value = new EntryInfo(entry, allocator);
++entries_count_;
}
-void HeapEntriesMap::CountReference(HeapObject* from, HeapObject* to,
+void HeapEntriesMap::CountReference(HeapThing from, HeapThing to,
int* prev_children_count,
int* prev_retainers_count) {
HashMap::Entry* from_cache_entry = entries_.Lookup(from, Hash(from), false);
@@ -1670,8 +1584,23 @@ void HeapEntriesMap::CountReference(HeapObject* from, HeapObject* to,
}
+void HeapEntriesMap::UpdateEntries() {
+ for (HashMap::Entry* p = entries_.Start();
+ p != NULL;
+ p = entries_.Next(p)) {
+ EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
+ entry_info->entry = entry_info->allocator->AllocateEntry(
+ p->key,
+ entry_info->children_count,
+ entry_info->retainers_count);
+ entry_info->children_count = 0;
+ entry_info->retainers_count = 0;
+ }
+}
+
+
HeapObjectsSet::HeapObjectsSet()
- : entries_(HeapEntriesMap::HeapObjectsMatch) {
+ : entries_(HeapEntriesMap::HeapThingsMatch) {
}
@@ -1700,206 +1629,144 @@ void HeapObjectsSet::Insert(Object* obj) {
}
-HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
- v8::ActivityControl* control)
+HeapObject *const V8HeapExplorer::kInternalRootObject =
+ reinterpret_cast<HeapObject*>(1);
+HeapObject *const V8HeapExplorer::kGcRootsObject =
+ reinterpret_cast<HeapObject*>(2);
+
+
+V8HeapExplorer::V8HeapExplorer(
+ HeapSnapshot* snapshot,
+ SnapshottingProgressReportingInterface* progress)
: snapshot_(snapshot),
- control_(control),
- collection_(snapshot->collection()),
+ collection_(snapshot_->collection()),
+ progress_(progress),
filler_(NULL) {
}
-class SnapshotCounter : public HeapSnapshotGenerator::SnapshotFillerInterface {
- public:
- explicit SnapshotCounter(HeapEntriesMap* entries)
- : entries_(entries) { }
- HeapEntry* AddEntry(HeapObject* obj) {
- entries_->Pair(obj, HeapEntriesMap::kHeapEntryPlaceholder);
- return HeapEntriesMap::kHeapEntryPlaceholder;
- }
- void SetIndexedReference(HeapGraphEdge::Type,
- HeapObject* parent_obj,
- HeapEntry*,
- int,
- Object* child_obj,
- HeapEntry*) {
- entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
- }
- void SetNamedReference(HeapGraphEdge::Type,
- HeapObject* parent_obj,
- HeapEntry*,
- const char*,
- Object* child_obj,
- HeapEntry*) {
- entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
- }
- void SetRootShortcutReference(Object* child_obj, HeapEntry*) {
- entries_->CountReference(
- HeapSnapshot::kInternalRootObject, HeapObject::cast(child_obj));
- }
- void SetRootGcRootsReference() {
- entries_->CountReference(
- HeapSnapshot::kInternalRootObject, HeapSnapshot::kGcRootsObject);
- }
- void SetStrongRootReference(Object* child_obj, HeapEntry*) {
- entries_->CountReference(
- HeapSnapshot::kGcRootsObject, HeapObject::cast(child_obj));
- }
- private:
- HeapEntriesMap* entries_;
-};
-
-
-class SnapshotFiller : public HeapSnapshotGenerator::SnapshotFillerInterface {
- public:
- explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
- : snapshot_(snapshot),
- collection_(snapshot->collection()),
- entries_(entries) { }
- HeapEntry* AddEntry(HeapObject* obj) {
- UNREACHABLE();
- return NULL;
- }
- void SetIndexedReference(HeapGraphEdge::Type type,
- HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(parent_obj,
- HeapObject::cast(child_obj),
- &child_index,
- &retainer_index);
- parent_entry->SetIndexedReference(
- type, child_index, index, child_entry, retainer_index);
- }
- void SetNamedReference(HeapGraphEdge::Type type,
- HeapObject* parent_obj,
- HeapEntry* parent_entry,
- const char* reference_name,
- Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(parent_obj, HeapObject::cast(child_obj),
- &child_index, &retainer_index);
- parent_entry->SetNamedReference(type,
- child_index,
- reference_name,
- child_entry,
- retainer_index);
- }
- void SetRootGcRootsReference() {
- int child_index, retainer_index;
- entries_->CountReference(HeapSnapshot::kInternalRootObject,
- HeapSnapshot::kGcRootsObject,
- &child_index,
- &retainer_index);
- snapshot_->root()->SetIndexedReference(HeapGraphEdge::kElement,
- child_index,
- child_index + 1,
- snapshot_->gc_roots(),
- retainer_index);
- }
- void SetRootShortcutReference(Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(HeapSnapshot::kInternalRootObject,
- HeapObject::cast(child_obj),
- &child_index,
- &retainer_index);
- snapshot_->root()->SetNamedReference(HeapGraphEdge::kShortcut,
- child_index,
- collection_->GetName(child_index + 1),
- child_entry,
- retainer_index);
- }
- void SetStrongRootReference(Object* child_obj,
- HeapEntry* child_entry) {
- int child_index, retainer_index;
- entries_->CountReference(HeapSnapshot::kGcRootsObject,
- HeapObject::cast(child_obj),
- &child_index,
- &retainer_index);
- snapshot_->gc_roots()->SetIndexedReference(HeapGraphEdge::kElement,
- child_index,
- child_index + 1,
- child_entry,
- retainer_index);
- }
- private:
- HeapSnapshot* snapshot_;
- HeapSnapshotsCollection* collection_;
- HeapEntriesMap* entries_;
-};
-class SnapshotAllocator {
- public:
- explicit SnapshotAllocator(HeapSnapshot* snapshot)
- : snapshot_(snapshot) { }
- HeapEntry* GetEntry(
- HeapObject* obj, int children_count, int retainers_count) {
- HeapEntry* entry =
- snapshot_->AddEntry(obj, children_count, retainers_count);
- ASSERT(entry != NULL);
- return entry;
- }
- private:
- HeapSnapshot* snapshot_;
-};
-
-class RootsReferencesExtractor : public ObjectVisitor {
- public:
- explicit RootsReferencesExtractor(HeapSnapshotGenerator* generator)
- : generator_(generator) {
- }
- void VisitPointers(Object** start, Object** end) {
- for (Object** p = start; p < end; p++) generator_->SetGcRootsReference(*p);
- }
- private:
- HeapSnapshotGenerator* generator_;
-};
+V8HeapExplorer::~V8HeapExplorer() {
+}
-bool HeapSnapshotGenerator::GenerateSnapshot() {
- AssertNoAllocation no_alloc;
+HeapEntry* V8HeapExplorer::AllocateEntry(
+ HeapThing ptr, int children_count, int retainers_count) {
+ return AddEntry(
+ reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count);
+}
- SetProgressTotal(4); // 2 passes + dominators + sizes.
- // Pass 1. Iterate heap contents to count entries and references.
- if (!CountEntriesAndReferences()) return false;
+HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
+ int children_count,
+ int retainers_count) {
+ if (object == kInternalRootObject) {
+ ASSERT(retainers_count == 0);
+ return snapshot_->AddRootEntry(children_count);
+ } else if (object == kGcRootsObject) {
+ return snapshot_->AddGcRootsEntry(children_count, retainers_count);
+ } else if (object->IsJSFunction()) {
+ JSFunction* func = JSFunction::cast(object);
+ SharedFunctionInfo* shared = func->shared();
+ return AddEntry(object,
+ HeapEntry::kClosure,
+ collection_->GetName(String::cast(shared->name())),
+ children_count,
+ retainers_count);
+ } else if (object->IsJSRegExp()) {
+ JSRegExp* re = JSRegExp::cast(object);
+ return AddEntry(object,
+ HeapEntry::kRegExp,
+ collection_->GetName(re->Pattern()),
+ children_count,
+ retainers_count);
+ } else if (object->IsJSObject()) {
+ return AddEntry(object,
+ HeapEntry::kObject,
+ collection_->GetName(GetConstructorNameForHeapProfile(
+ JSObject::cast(object))),
+ children_count,
+ retainers_count);
+ } else if (object->IsString()) {
+ return AddEntry(object,
+ HeapEntry::kString,
+ collection_->GetName(String::cast(object)),
+ children_count,
+ retainers_count);
+ } else if (object->IsCode()) {
+ return AddEntry(object,
+ HeapEntry::kCode,
+ "",
+ children_count,
+ retainers_count);
+ } else if (object->IsSharedFunctionInfo()) {
+ SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
+ return AddEntry(object,
+ HeapEntry::kCode,
+ collection_->GetName(String::cast(shared->name())),
+ children_count,
+ retainers_count);
+ } else if (object->IsScript()) {
+ Script* script = Script::cast(object);
+ return AddEntry(object,
+ HeapEntry::kCode,
+ script->name()->IsString() ?
+ collection_->GetName(String::cast(script->name())) : "",
+ children_count,
+ retainers_count);
+ } else if (object->IsFixedArray()) {
+ return AddEntry(object,
+ HeapEntry::kArray,
+ "",
+ children_count,
+ retainers_count);
+ } else if (object->IsHeapNumber()) {
+ return AddEntry(object,
+ HeapEntry::kHeapNumber,
+ "number",
+ children_count,
+ retainers_count);
+ }
+ return AddEntry(object,
+ HeapEntry::kHidden,
+ "system",
+ children_count,
+ retainers_count);
+}
- // Allocate and fill entries in the snapshot, allocate references.
- snapshot_->AllocateEntries(entries_.entries_count(),
- entries_.total_children_count(),
- entries_.total_retainers_count());
- SnapshotAllocator allocator(snapshot_);
- entries_.UpdateEntries(&allocator);
- // Pass 2. Fill references.
- if (!FillReferences()) return false;
+HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
+ HeapEntry::Type type,
+ const char* name,
+ int children_count,
+ int retainers_count) {
+ return snapshot_->AddEntry(type,
+ name,
+ collection_->GetObjectId(object->address()),
+ object->Size(),
+ children_count,
+ retainers_count);
+}
- if (!SetEntriesDominators()) return false;
- if (!ApproximateRetainedSizes()) return false;
- progress_counter_ = progress_total_;
- if (!ReportProgress(true)) return false;
- return true;
+void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
+ filler->AddEntry(kInternalRootObject);
+ filler->AddEntry(kGcRootsObject);
}
-HeapEntry* HeapSnapshotGenerator::GetEntry(Object* obj) {
- if (!obj->IsHeapObject()) return NULL;
- HeapObject* object = HeapObject::cast(obj);
- HeapEntry* entry = entries_.Map(object);
- // A new entry.
- if (entry == NULL) entry = filler_->AddEntry(object);
- return entry;
+int V8HeapExplorer::EstimateObjectsCount() {
+ HeapIterator iterator(HeapIterator::kFilterUnreachable);
+ int objects_count = 0;
+ for (HeapObject* obj = iterator.next();
+ obj != NULL;
+ obj = iterator.next(), ++objects_count) {}
+ return objects_count;
}
class IndexedReferencesExtractor : public ObjectVisitor {
public:
- IndexedReferencesExtractor(HeapSnapshotGenerator* generator,
+ IndexedReferencesExtractor(V8HeapExplorer* generator,
HeapObject* parent_obj,
HeapEntry* parent_entry,
HeapObjectsSet* known_references = NULL)
@@ -1917,7 +1784,7 @@ class IndexedReferencesExtractor : public ObjectVisitor {
}
}
private:
- HeapSnapshotGenerator* generator_;
+ V8HeapExplorer* generator_;
HeapObject* parent_obj_;
HeapEntry* parent_;
HeapObjectsSet* known_references_;
@@ -1925,7 +1792,7 @@ class IndexedReferencesExtractor : public ObjectVisitor {
};
-void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) {
+void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
HeapEntry* entry = GetEntry(obj);
if (entry == NULL) return; // No interest in this object.
@@ -1969,8 +1836,8 @@ void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) {
}
-void HeapSnapshotGenerator::ExtractClosureReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
+ HeapEntry* entry) {
if (js_obj->IsJSFunction()) {
HandleScope hs;
JSFunction* func = JSFunction::cast(js_obj);
@@ -1992,8 +1859,8 @@ void HeapSnapshotGenerator::ExtractClosureReferences(JSObject* js_obj,
}
-void HeapSnapshotGenerator::ExtractPropertyReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
+ HeapEntry* entry) {
if (js_obj->HasFastProperties()) {
DescriptorArray* descs = js_obj->map()->instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) {
@@ -2034,8 +1901,8 @@ void HeapSnapshotGenerator::ExtractPropertyReferences(JSObject* js_obj,
}
-void HeapSnapshotGenerator::ExtractElementReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
+ HeapEntry* entry) {
if (js_obj->HasFastElements()) {
FixedArray* elements = FixedArray::cast(js_obj->elements());
int length = js_obj->IsJSArray() ?
@@ -2061,8 +1928,8 @@ void HeapSnapshotGenerator::ExtractElementReferences(JSObject* js_obj,
}
-void HeapSnapshotGenerator::ExtractInternalReferences(JSObject* js_obj,
- HeapEntry* entry) {
+void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
+ HeapEntry* entry) {
int length = js_obj->GetInternalFieldCount();
for (int i = 0; i < length; ++i) {
Object* o = js_obj->GetInternalField(i);
@@ -2071,10 +1938,55 @@ void HeapSnapshotGenerator::ExtractInternalReferences(JSObject* js_obj,
}
-void HeapSnapshotGenerator::SetClosureReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- String* reference_name,
- Object* child_obj) {
+HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
+ if (!obj->IsHeapObject()) return NULL;
+ return filler_->FindOrAddEntry(obj);
+}
+
+
+class RootsReferencesExtractor : public ObjectVisitor {
+ public:
+ explicit RootsReferencesExtractor(V8HeapExplorer* explorer)
+ : explorer_(explorer) {
+ }
+ void VisitPointers(Object** start, Object** end) {
+ for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p);
+ }
+ private:
+ V8HeapExplorer* explorer_;
+};
+
+
+bool V8HeapExplorer::IterateAndExtractReferences(
+ SnapshotFillerInterface* filler) {
+ filler_ = filler;
+ HeapIterator iterator(HeapIterator::kFilterUnreachable);
+ bool interrupted = false;
+ // Heap iteration with filtering must be finished in any case.
+ for (HeapObject* obj = iterator.next();
+ obj != NULL;
+ obj = iterator.next(), progress_->ProgressStep()) {
+ if (!interrupted) {
+ ExtractReferences(obj);
+ if (!progress_->ProgressReport(false)) interrupted = true;
+ }
+ }
+ if (interrupted) {
+ filler_ = NULL;
+ return false;
+ }
+ SetRootGcRootsReference();
+ RootsReferencesExtractor extractor(this);
+ Heap::IterateRoots(&extractor, VISIT_ALL);
+ filler_ = NULL;
+ return progress_->ProgressReport(false);
+}
+
+
+void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ String* reference_name,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
@@ -2088,10 +2000,10 @@ void HeapSnapshotGenerator::SetClosureReference(HeapObject* parent_obj,
}
-void HeapSnapshotGenerator::SetElementReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj) {
+void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ int index,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetIndexedReference(HeapGraphEdge::kElement,
@@ -2105,10 +2017,10 @@ void HeapSnapshotGenerator::SetElementReference(HeapObject* parent_obj,
}
-void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- const char* reference_name,
- Object* child_obj) {
+void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ const char* reference_name,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kInternal,
@@ -2122,10 +2034,10 @@ void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
}
-void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj) {
+void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ int index,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kInternal,
@@ -2139,10 +2051,10 @@ void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
}
-void HeapSnapshotGenerator::SetHiddenReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- int index,
- Object* child_obj) {
+void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ int index,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetIndexedReference(HeapGraphEdge::kHidden,
@@ -2155,10 +2067,10 @@ void HeapSnapshotGenerator::SetHiddenReference(HeapObject* parent_obj,
}
-void HeapSnapshotGenerator::SetPropertyReference(HeapObject* parent_obj,
- HeapEntry* parent_entry,
- String* reference_name,
- Object* child_obj) {
+void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
+ HeapEntry* parent_entry,
+ String* reference_name,
+ Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
HeapGraphEdge::Type type = reference_name->length() > 0 ?
@@ -2174,7 +2086,7 @@ void HeapSnapshotGenerator::SetPropertyReference(HeapObject* parent_obj,
}
-void HeapSnapshotGenerator::SetPropertyShortcutReference(
+void V8HeapExplorer::SetPropertyShortcutReference(
HeapObject* parent_obj,
HeapEntry* parent_entry,
String* reference_name,
@@ -2191,52 +2103,221 @@ void HeapSnapshotGenerator::SetPropertyShortcutReference(
}
-void HeapSnapshotGenerator::SetRootGcRootsReference() {
- filler_->SetRootGcRootsReference();
+void V8HeapExplorer::SetRootGcRootsReference() {
+ filler_->SetIndexedAutoIndexReference(
+ HeapGraphEdge::kElement,
+ kInternalRootObject, snapshot_->root(),
+ kGcRootsObject, snapshot_->gc_roots());
}
-void HeapSnapshotGenerator::SetRootShortcutReference(Object* child_obj) {
+void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
ASSERT(child_entry != NULL);
- filler_->SetRootShortcutReference(child_obj, child_entry);
+ filler_->SetNamedAutoIndexReference(
+ HeapGraphEdge::kShortcut,
+ kInternalRootObject, snapshot_->root(),
+ child_obj, child_entry);
}
-void HeapSnapshotGenerator::SetGcRootsReference(Object* child_obj) {
+void V8HeapExplorer::SetGcRootsReference(Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
- filler_->SetStrongRootReference(child_obj, child_entry);
+ filler_->SetIndexedAutoIndexReference(
+ HeapGraphEdge::kElement,
+ kGcRootsObject, snapshot_->gc_roots(),
+ child_obj, child_entry);
}
}
+HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
+ v8::ActivityControl* control)
+ : snapshot_(snapshot),
+ control_(control),
+ v8_heap_explorer_(snapshot_, this) {
+}
+
+
+class SnapshotCounter : public SnapshotFillerInterface {
+ public:
+ SnapshotCounter(HeapEntriesAllocator* allocator, HeapEntriesMap* entries)
+ : allocator_(allocator), entries_(entries) { }
+ HeapEntry* AddEntry(HeapThing ptr) {
+ entries_->Pair(ptr, allocator_, HeapEntriesMap::kHeapEntryPlaceholder);
+ return HeapEntriesMap::kHeapEntryPlaceholder;
+ }
+ HeapEntry* FindOrAddEntry(HeapThing ptr) {
+ HeapEntry* entry = entries_->Map(ptr);
+ return entry != NULL ? entry : AddEntry(ptr);
+ }
+ void SetIndexedReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ int,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ void SetIndexedAutoIndexReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ void SetNamedReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ const char*,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ void SetNamedAutoIndexReference(HeapGraphEdge::Type,
+ HeapThing parent_ptr,
+ HeapEntry*,
+ HeapThing child_ptr,
+ HeapEntry*) {
+ entries_->CountReference(parent_ptr, child_ptr);
+ }
+ private:
+ HeapEntriesAllocator* allocator_;
+ HeapEntriesMap* entries_;
+};
+
+
+class SnapshotFiller : public SnapshotFillerInterface {
+ public:
+ explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
+ : snapshot_(snapshot),
+ collection_(snapshot->collection()),
+ entries_(entries) { }
+ HeapEntry* AddEntry(HeapThing ptr) {
+ UNREACHABLE();
+ return NULL;
+ }
+ HeapEntry* FindOrAddEntry(HeapThing ptr) {
+ HeapEntry* entry = entries_->Map(ptr);
+ return entry != NULL ? entry : AddEntry(ptr);
+ }
+ void SetIndexedReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ int index,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetIndexedReference(
+ type, child_index, index, child_entry, retainer_index);
+ }
+ void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetIndexedReference(
+ type, child_index, child_index + 1, child_entry, retainer_index);
+ }
+ void SetNamedReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ const char* reference_name,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetNamedReference(
+ type, child_index, reference_name, child_entry, retainer_index);
+ }
+ void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
+ HeapThing parent_ptr,
+ HeapEntry* parent_entry,
+ HeapThing child_ptr,
+ HeapEntry* child_entry) {
+ int child_index, retainer_index;
+ entries_->CountReference(
+ parent_ptr, child_ptr, &child_index, &retainer_index);
+ parent_entry->SetNamedReference(type,
+ child_index,
+ collection_->GetName(child_index + 1),
+ child_entry,
+ retainer_index);
+ }
+ private:
+ HeapSnapshot* snapshot_;
+ HeapSnapshotsCollection* collection_;
+ HeapEntriesMap* entries_;
+};
+
+
+bool HeapSnapshotGenerator::GenerateSnapshot() {
+ AssertNoAllocation no_alloc;
+
+ SetProgressTotal(4); // 2 passes + dominators + sizes.
+
+ // Pass 1. Iterate heap contents to count entries and references.
+ if (!CountEntriesAndReferences()) return false;
+
+ // Allocate and fill entries in the snapshot, allocate references.
+ snapshot_->AllocateEntries(entries_.entries_count(),
+ entries_.total_children_count(),
+ entries_.total_retainers_count());
+ entries_.UpdateEntries();
+
+ // Pass 2. Fill references.
+ if (!FillReferences()) return false;
+
+ if (!SetEntriesDominators()) return false;
+ if (!ApproximateRetainedSizes()) return false;
+
+ progress_counter_ = progress_total_;
+ if (!ProgressReport(true)) return false;
+ return true;
+}
+
+
+void HeapSnapshotGenerator::ProgressStep() {
+ ++progress_counter_;
+}
+
+
+bool HeapSnapshotGenerator::ProgressReport(bool force) {
+ const int kProgressReportGranularity = 10000;
+ if (control_ != NULL
+ && (force || progress_counter_ % kProgressReportGranularity == 0)) {
+ return
+ control_->ReportProgressValue(progress_counter_, progress_total_) ==
+ v8::ActivityControl::kContinue;
+ }
+ return true;
+}
+
+
void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
if (control_ == NULL) return;
-
- HeapIterator iterator(HeapIterator::kFilterUnreachable);
- int objects_count = 0;
- for (HeapObject* obj = iterator.next();
- obj != NULL;
- obj = iterator.next(), ++objects_count) {}
- progress_total_ = objects_count * iterations_count;
+ progress_total_ = v8_heap_explorer_.EstimateObjectsCount() * iterations_count;
progress_counter_ = 0;
}
bool HeapSnapshotGenerator::CountEntriesAndReferences() {
- SnapshotCounter counter(&entries_);
- filler_ = &counter;
- filler_->AddEntry(HeapSnapshot::kInternalRootObject);
- filler_->AddEntry(HeapSnapshot::kGcRootsObject);
- return IterateAndExtractReferences();
+ SnapshotCounter counter(&v8_heap_explorer_, &entries_);
+ v8_heap_explorer_.AddRootEntries(&counter);
+ return v8_heap_explorer_.IterateAndExtractReferences(&counter);
}
bool HeapSnapshotGenerator::FillReferences() {
SnapshotFiller filler(snapshot_, &entries_);
- filler_ = &filler;
- return IterateAndExtractReferences();
+ return v8_heap_explorer_.IterateAndExtractReferences(&filler);
}
@@ -2322,7 +2403,7 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
int remaining = entries_length - changed;
if (remaining < 0) remaining = 0;
progress_counter_ = base_progress_counter + remaining;
- if (!ReportProgress(true)) return false;
+ if (!ProgressReport(true)) return false;
}
return true;
}
@@ -2352,7 +2433,7 @@ bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
}
for (int i = 0;
i < snapshot_->entries()->length();
- ++i, IncProgressCounter()) {
+ ++i, ProgressStep()) {
HeapEntry* entry = snapshot_->entries()->at(i);
int entry_size = entry->self_size();
for (HeapEntry* dominator = entry->dominator();
@@ -2360,32 +2441,12 @@ bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
entry = dominator, dominator = entry->dominator()) {
dominator->add_retained_size(entry_size);
}
- if (!ReportProgress()) return false;
+ if (!ProgressReport()) return false;
}
return true;
}
-bool HeapSnapshotGenerator::IterateAndExtractReferences() {
- HeapIterator iterator(HeapIterator::kFilterUnreachable);
- bool interrupted = false;
- // Heap iteration with filtering must be finished in any case.
- for (HeapObject* obj = iterator.next();
- obj != NULL;
- obj = iterator.next(), IncProgressCounter()) {
- if (!interrupted) {
- ExtractReferences(obj);
- if (!ReportProgress()) interrupted = true;
- }
- }
- if (interrupted) return false;
- SetRootGcRootsReference();
- RootsReferencesExtractor extractor(this);
- Heap::IterateRoots(&extractor, VISIT_ALL);
- return ReportProgress();
-}
-
-
void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) {
raw_additions_root_ =
NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0));

Powered by Google App Engine
This is Rietveld 408576698