Index: src/profile-generator.cc |
=================================================================== |
--- src/profile-generator.cc (revision 10671) |
+++ src/profile-generator.cc (working copy) |
@@ -1775,9 +1775,11 @@ |
} else if (object->IsJSFunction()) { |
JSFunction* func = JSFunction::cast(object); |
SharedFunctionInfo* shared = func->shared(); |
+ const char* name = shared->bound() ? "native bind" : |
+ collection_->names()->GetName(String::cast(shared->name())); |
return AddEntry(object, |
HeapEntry::kClosure, |
- collection_->names()->GetName(String::cast(shared->name())), |
+ name, |
children_count, |
retainers_count); |
} else if (object->IsJSRegExp()) { |
@@ -2018,12 +2020,20 @@ |
SetInternalReference(js_fun, entry, |
"context", js_fun->unchecked_context(), |
JSFunction::kContextOffset); |
- TagObject(js_fun->literals_or_bindings(), |
- "(function literals_or_bindings)"); |
- SetInternalReference(js_fun, entry, |
- "literals_or_bindings", |
- js_fun->literals_or_bindings(), |
- JSFunction::kLiteralsOffset); |
+ // JSFunction has either bindings or literals and never both. |
+ if (js_fun->shared()->bound()) { |
+ TagObject(js_fun->literals(), "(function literals)"); |
+ SetInternalReference(js_fun, entry, |
+ "literals", |
+ js_fun->literals(), |
+ JSFunction::kLiteralsOffset); |
+ } else { |
+ TagObject(js_fun->function_bindings(), "(function bindings)"); |
+ SetInternalReference(js_fun, entry, |
+ "bindings", |
+ js_fun->function_bindings(), |
+ JSFunction::kLiteralsOffset); |
+ } |
for (int i = JSFunction::kNonWeakFieldsEndOffset; |
i < JSFunction::kSize; |
i += kPointerSize) { |
@@ -2126,17 +2136,6 @@ |
SetInternalReference(obj, entry, |
"line_ends", script->line_ends(), |
Script::kLineEndsOffset); |
- } else if (obj->IsDescriptorArray()) { |
yurys
2012/02/10 11:30:14
DescriptorArray is indistinguishable from a regula
mnaganov (inactive)
2012/02/10 12:28:21
OK, thanks!
|
- DescriptorArray* desc_array = DescriptorArray::cast(obj); |
- if (desc_array->length() > DescriptorArray::kContentArrayIndex) { |
- Object* content_array = |
- desc_array->get(DescriptorArray::kContentArrayIndex); |
- TagObject(content_array, "(map descriptor content)"); |
- SetInternalReference(obj, entry, |
- "content", content_array, |
- FixedArray::OffsetOfElementAt( |
- DescriptorArray::kContentArrayIndex)); |
- } |
} else if (obj->IsCodeCache()) { |
CodeCache* code_cache = CodeCache::cast(obj); |
TagObject(code_cache->default_cache(), "(default code cache)"); |
@@ -2162,11 +2161,24 @@ |
void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, |
HeapEntry* entry) { |
- if (js_obj->IsJSFunction()) { |
- JSFunction* func = JSFunction::cast(js_obj); |
- Context* context = func->context(); |
- ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
+ if (!js_obj->IsJSFunction()) return; |
+ JSFunction* func = JSFunction::cast(js_obj); |
+ Context* context = func->context(); |
+ ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
+ |
+ if (func->shared()->bound()) { |
+ FixedArray* bindings = func->function_bindings(); |
+ SetNativeBindReference(js_obj, entry, "bound this", |
mnaganov (inactive)
2012/02/10 12:28:21
Perhaps, use underscores for names? Otherwise it m
yurys
2012/02/10 13:48:59
Makes sense. Done.
|
+ bindings->get(JSFunction::kBoundThisIndex)); |
+ SetNativeBindReference(js_obj, entry, "bound function", |
+ bindings->get(JSFunction::kBoundFunctionIndex)); |
+ for (int i = JSFunction::kBoundArgumentsStartIndex; |
+ i < bindings->length(); i++) { |
+ SetNativeBindReference(js_obj, entry, "bound argument", |
mnaganov (inactive)
2012/02/10 12:28:21
Does it make sense to label them "bound_argument_%
yurys
2012/02/10 13:48:59
Done.
|
+ bindings->get(i)); |
+ } |
+ } else { |
// Add context allocated locals. |
int context_locals = scope_info->ContextLocalCount(); |
for (int i = 0; i < context_locals; ++i) { |
@@ -2444,6 +2456,22 @@ |
} |
+void V8HeapExplorer::SetNativeBindReference(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::kShortcut, |
+ parent_obj, |
+ parent_entry, |
+ reference_name, |
+ child_obj, |
+ child_entry); |
+ } |
+} |
+ |
+ |
void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, |
HeapEntry* parent_entry, |
int index, |