Revision: 5612
Author: [email protected]
Date: Wed Oct 13 07:57:00 2010
Log: Better align heap snapshots contents with debugger info.
I created a heap snapshot in Chromium, and then started comparing
it side-by-side with representations of objects provided by
the debugger, fixing discrepancies.
Review URL: http://codereview.chromium.org/3590029
http://code.google.com/p/v8/source/detail?r=5612
Modified:
/branches/bleeding_edge/include/v8-profiler.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/profile-generator.cc
/branches/bleeding_edge/src/profile-generator.h
/branches/bleeding_edge/test/cctest/test-heap-profiler.cc
=======================================
--- /branches/bleeding_edge/include/v8-profiler.h Tue Sep 14 04:49:06 2010
+++ /branches/bleeding_edge/include/v8-profiler.h Wed Oct 13 07:57:00 2010
@@ -245,7 +245,8 @@
kString = 2, // A string.
kObject = 3, // A JS object (except for arrays and strings).
kCode = 4, // Compiled code.
- kClosure = 5 // Function closure.
+ kClosure = 5, // Function closure.
+ kRegExp = 6 // RegExp.
};
/** Returns node type (see HeapGraphNode::Type). */
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue Oct 5 06:10:43 2010
+++ /branches/bleeding_edge/src/objects.cc Wed Oct 13 07:57:00 2010
@@ -1180,7 +1180,11 @@
if (map()->constructor()->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(map()->constructor());
String* name = String::cast(constructor->shared()->name());
- return name->length() > 0 ? name :
constructor->shared()->inferred_name();
+ if (name->length() > 0) return name;
+ String* inferred_name = constructor->shared()->inferred_name();
+ if (inferred_name->length() > 0) return inferred_name;
+ Object* proto = GetPrototype();
+ if (proto->IsJSObject()) return
JSObject::cast(proto)->constructor_name();
}
// If the constructor is not present, return "Object".
return Heap::Object_symbol();
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Fri Oct 1 00:19:23
2010
+++ /branches/bleeding_edge/src/profile-generator.cc Wed Oct 13 07:57:00
2010
@@ -1001,6 +1001,7 @@
case kString: return "/string/";
case kCode: return "/code/";
case kArray: return "/array/";
+ case kRegExp: return "/regexp/";
default: return "???";
}
}
@@ -1284,11 +1285,16 @@
} else if (object->IsJSFunction()) {
JSFunction* func = JSFunction::cast(object);
SharedFunctionInfo* shared = func->shared();
- String* name = String::cast(shared->name())->length() > 0 ?
- String::cast(shared->name()) : shared->inferred_name();
return AddEntry(object,
HeapEntry::kClosure,
- collection_->GetFunctionName(name),
+ 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()) {
@@ -1342,6 +1348,7 @@
bool HeapSnapshot::WillAddEntry(HeapObject* object) {
return object == kInternalRootObject
|| object->IsJSFunction()
+ || object->IsJSRegExp()
|| object->IsJSObject()
|| object->IsString()
|| object->IsCode()
@@ -1905,12 +1912,19 @@
ExtractPropertyReferences(js_obj, entry);
ExtractElementReferences(js_obj, entry);
SetPropertyReference(
- obj, entry, Heap::prototype_symbol(), js_obj->map()->prototype());
+ 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());
+ }
+ }
} else if (obj->IsString()) {
if (obj->IsConsString()) {
ConsString* cs = ConsString::cast(obj);
- SetElementReference(obj, entry, 0, cs->first());
- SetElementReference(obj, entry, 1, cs->second());
+ SetInternalReference(obj, entry, "1", cs->first());
+ SetInternalReference(obj, entry, "2", cs->second());
}
} else if (obj->IsCode() || obj->IsSharedFunctionInfo() ||
obj->IsScript()) {
IndexedReferencesExtractor refs_extractor(this, obj, entry);
@@ -2055,7 +2069,9 @@
Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
- filler_->SetNamedReference(HeapGraphEdge::kProperty,
+ HeapGraphEdge::Type type = reference_name->length() > 0 ?
+ HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
+ filler_->SetNamedReference(type,
parent_obj,
parent_entry,
collection_->GetName(reference_name),
@@ -2351,7 +2367,8 @@
"," JSON_S("string")
"," JSON_S("object")
"," JSON_S("code")
- "," JSON_S("closure"))
+ "," JSON_S("closure")
+ "," JSON_S("regexp"))
"," JSON_S("string")
"," JSON_S("number")
"," JSON_S("number")
=======================================
--- /branches/bleeding_edge/src/profile-generator.h Fri Oct 1 00:19:23 2010
+++ /branches/bleeding_edge/src/profile-generator.h Wed Oct 13 07:57:00 2010
@@ -502,7 +502,8 @@
kString = v8::HeapGraphNode::kString,
kObject = v8::HeapGraphNode::kObject,
kCode = v8::HeapGraphNode::kCode,
- kClosure = v8::HeapGraphNode::kClosure
+ kClosure = v8::HeapGraphNode::kClosure,
+ kRegExp = v8::HeapGraphNode::kRegExp
};
HeapEntry() { }
=======================================
--- /branches/bleeding_edge/test/cctest/test-heap-profiler.cc Fri Oct 1
00:19:23 2010
+++ /branches/bleeding_edge/test/cctest/test-heap-profiler.cc Wed Oct 13
07:57:00 2010
@@ -594,7 +594,7 @@
GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
CHECK_NE(NULL, x);
const v8::HeapGraphNode* x_prototype =
- GetProperty(x, v8::HeapGraphEdge::kProperty, "prototype");
+ GetProperty(x, v8::HeapGraphEdge::kProperty, "__proto__");
CHECK_NE(NULL, x_prototype);
const v8::HeapGraphNode* x1 =
GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
@@ -606,7 +606,7 @@
x->GetSelfSize() * 3,
x->GetReachableSize() - x_prototype->GetReachableSize());
CHECK_EQ(
- x->GetSelfSize() * 3 + x_prototype->GetSelfSize(),
x->GetRetainedSize());
+ x->GetSelfSize() * 3, x->GetRetainedSize());
CHECK_EQ(
x1->GetSelfSize() * 2,
x1->GetReachableSize() - x_prototype->GetReachableSize());
@@ -651,7 +651,6 @@
CompileAndRunScript(
"function lazy(x) { return x - 1; }\n"
"function compiled(x) { return x + 1; }\n"
- "var inferred = function(x) { return x; }\n"
"var anonymous = (function() { return function() { return 0; }
})();\n"
"compiled(1)");
const v8::HeapSnapshot* snapshot =
@@ -666,18 +665,12 @@
GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
CHECK_NE(NULL, lazy);
CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
- const v8::HeapGraphNode* inferred =
- GetProperty(global, v8::HeapGraphEdge::kProperty, "inferred");
- CHECK_NE(NULL, inferred);
- CHECK_EQ(v8::HeapGraphNode::kClosure, inferred->GetType());
- v8::String::AsciiValue inferred_name(inferred->GetName());
- CHECK_EQ("inferred", *inferred_name);
const v8::HeapGraphNode* anonymous =
GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous");
CHECK_NE(NULL, anonymous);
CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType());
v8::String::AsciiValue anonymous_name(anonymous->GetName());
- CHECK_EQ("(anonymous function)", *anonymous_name);
+ CHECK_EQ("", *anonymous_name);
// Find references to code.
const v8::HeapGraphNode* compiled_code =
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev