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

Unified Diff: src/profile-generator.cc

Issue 6665038: Dramatically speed up detailed heap snapshot generation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments addressed Created 9 years, 9 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
« no previous file with comments | « src/profile-generator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profile-generator.cc
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 099b9dfa21e93073b280addfc9deb5c8019c9a95..a63901f1736e42a27dc623df81b96d056b8372ae 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -1826,25 +1826,40 @@ class IndexedReferencesExtractor : public ObjectVisitor {
IndexedReferencesExtractor(V8HeapExplorer* generator,
HeapObject* parent_obj,
HeapEntry* parent_entry,
- HeapObjectsSet* known_references = NULL)
+ bool process_field_marks = false)
: generator_(generator),
parent_obj_(parent_obj),
parent_(parent_entry),
- known_references_(known_references),
+ process_field_marks_(process_field_marks),
next_index_(1) {
}
void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) {
- if (!known_references_ || !known_references_->Contains(*p)) {
- generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
- }
+ if (CheckVisitedAndUnmark(p)) continue;
+ generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
}
}
+ static void MarkVisitedField(HeapObject* obj, int offset) {
+ if (offset < 0) return;
+ Address field = obj->address() + offset;
+ ASSERT(!Memory::Object_at(field)->IsFailure());
+ ASSERT(Memory::Object_at(field)->IsHeapObject());
+ *field |= kFailureTag;
+ }
private:
+ bool CheckVisitedAndUnmark(Object** field) {
+ if (process_field_marks_ && (*field)->IsFailure()) {
+ intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask;
+ *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag);
+ ASSERT((*field)->IsHeapObject());
+ return true;
+ }
+ return false;
+ }
V8HeapExplorer* generator_;
HeapObject* parent_obj_;
HeapEntry* parent_;
- HeapObjectsSet* known_references_;
+ bool process_field_marks_;
int next_index_;
};
@@ -1853,7 +1868,6 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
HeapEntry* entry = GetEntry(obj);
if (entry == NULL) return; // No interest in this object.
- known_references_.Clear();
if (obj->IsJSGlobalProxy()) {
// We need to reference JS global objects from snapshot's root.
// We use JSGlobalProxy because this is what embedder (e.g. browser)
@@ -1868,17 +1882,29 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
ExtractPropertyReferences(js_obj, entry);
ExtractElementReferences(js_obj, entry);
ExtractInternalReferences(js_obj, entry);
- SetPropertyReference(
- obj, entry, Heap::Proto_symbol(), js_obj->GetPrototype());
+ SetPropertyReference(obj, entry,
+ Heap::Proto_symbol(), js_obj->GetPrototype());
if (obj->IsJSFunction()) {
- JSFunction* js_fun = JSFunction::cast(obj);
- if (js_fun->has_prototype()) {
- SetPropertyReference(
- obj, entry, Heap::prototype_symbol(), js_fun->prototype());
+ JSFunction* js_fun = JSFunction::cast(js_obj);
+ SetInternalReference(
+ js_fun, entry,
+ "code", js_fun->shared(),
+ JSFunction::kSharedFunctionInfoOffset);
+ Object* proto_or_map = js_fun->prototype_or_initial_map();
+ if (!proto_or_map->IsTheHole()) {
+ if (!proto_or_map->IsMap()) {
+ SetPropertyReference(
+ obj, entry,
+ Heap::prototype_symbol(), proto_or_map,
+ JSFunction::kPrototypeOrInitialMapOffset);
+ } else {
+ SetPropertyReference(
+ obj, entry,
+ Heap::prototype_symbol(), js_fun->prototype());
+ }
}
}
- IndexedReferencesExtractor refs_extractor(
- this, obj, entry, &known_references_);
+ IndexedReferencesExtractor refs_extractor(this, obj, entry, true);
obj->Iterate(&refs_extractor);
} else if (obj->IsString()) {
if (obj->IsConsString()) {
@@ -1911,7 +1937,6 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
SetClosureReference(js_obj, entry, local_name, context->get(idx));
}
}
- SetInternalReference(js_obj, entry, "code", func->shared());
}
}
@@ -1924,13 +1949,22 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
switch (descs->GetType(i)) {
case FIELD: {
int index = descs->GetFieldIndex(i);
- SetPropertyReference(
- js_obj, entry, descs->GetKey(i), js_obj->FastPropertyAt(index));
+ if (index - js_obj->map()->inobject_properties() < 0) {
Vitaly Repeshko 2011/03/18 12:36:03 nit: It's probably more natural to write "index <
mnaganov (inactive) 2011/03/18 12:46:34 Sure. I also have noted this afterwards.
+ SetPropertyReference(
+ js_obj, entry,
+ descs->GetKey(i), js_obj->InObjectPropertyAt(index),
+ js_obj->GetInObjectPropertyOffset(index));
+ } else {
+ SetPropertyReference(
+ js_obj, entry,
+ descs->GetKey(i), js_obj->FastPropertyAt(index));
+ }
break;
}
case CONSTANT_FUNCTION:
SetPropertyReference(
- js_obj, entry, descs->GetKey(i), descs->GetConstantFunction(i));
+ js_obj, entry,
+ descs->GetKey(i), descs->GetConstantFunction(i));
break;
default: ;
}
@@ -1990,7 +2024,8 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
int length = js_obj->GetInternalFieldCount();
for (int i = 0; i < length; ++i) {
Object* o = js_obj->GetInternalField(i);
- SetInternalReference(js_obj, entry, i, o);
+ SetInternalReference(
+ js_obj, entry, i, o, js_obj->GetInternalFieldOffset(i));
}
}
@@ -2052,7 +2087,6 @@ void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
collection_->names()->GetName(reference_name),
child_obj,
child_entry);
- known_references_.Insert(child_obj);
}
}
@@ -2069,7 +2103,6 @@ void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
index,
child_obj,
child_entry);
- known_references_.Insert(child_obj);
}
}
@@ -2077,7 +2110,8 @@ void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
HeapEntry* parent_entry,
const char* reference_name,
- Object* child_obj) {
+ Object* child_obj,
+ int field_offset) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kInternal,
@@ -2086,7 +2120,7 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
reference_name,
child_obj,
child_entry);
- known_references_.Insert(child_obj);
+ IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
}
}
@@ -2094,7 +2128,8 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
HeapEntry* parent_entry,
int index,
- Object* child_obj) {
+ Object* child_obj,
+ int field_offset) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kInternal,
@@ -2103,7 +2138,7 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
collection_->names()->GetName(index),
child_obj,
child_entry);
- known_references_.Insert(child_obj);
+ IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
}
}
@@ -2127,7 +2162,8 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
HeapEntry* parent_entry,
String* reference_name,
- Object* child_obj) {
+ Object* child_obj,
+ int field_offset) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
HeapGraphEdge::Type type = reference_name->length() > 0 ?
@@ -2138,16 +2174,15 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
collection_->names()->GetName(reference_name),
child_obj,
child_entry);
- known_references_.Insert(child_obj);
+ IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
}
}
-void V8HeapExplorer::SetPropertyShortcutReference(
- HeapObject* parent_obj,
- HeapEntry* parent_entry,
- String* reference_name,
- Object* child_obj) {
+void V8HeapExplorer::SetPropertyShortcutReference(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::kShortcut,
« no previous file with comments | « src/profile-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698