Chromium Code Reviews| 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, |