| 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()) {
|
| @@ -2011,19 +2013,22 @@
|
| heap_->prototype_symbol(), js_fun->prototype());
|
| }
|
| }
|
| + SharedFunctionInfo* shared_info = js_fun->shared();
|
| + // JSFunction has either bindings or literals and never both.
|
| + bool bound = shared_info->bound();
|
| + TagObject(js_fun->literals_or_bindings(),
|
| + bound ? "(function bindings)" : "(function literals)");
|
| SetInternalReference(js_fun, entry,
|
| - "shared", js_fun->shared(),
|
| + bound ? "bindings" : "literals",
|
| + js_fun->literals_or_bindings(),
|
| + JSFunction::kLiteralsOffset);
|
| + SetInternalReference(js_fun, entry,
|
| + "shared", shared_info,
|
| JSFunction::kSharedFunctionInfoOffset);
|
| TagObject(js_fun->unchecked_context(), "(context)");
|
| 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);
|
| for (int i = JSFunction::kNonWeakFieldsEndOffset;
|
| i < JSFunction::kSize;
|
| i += kPointerSize) {
|
| @@ -2126,17 +2131,6 @@
|
| SetInternalReference(obj, entry,
|
| "line_ends", script->line_ends(),
|
| Script::kLineEndsOffset);
|
| - } else if (obj->IsDescriptorArray()) {
|
| - 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 +2156,27 @@
|
|
|
| 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",
|
| + bindings->get(JSFunction::kBoundThisIndex));
|
| + SetNativeBindReference(js_obj, entry, "bound_function",
|
| + bindings->get(JSFunction::kBoundFunctionIndex));
|
| + for (int i = JSFunction::kBoundArgumentsStartIndex;
|
| + i < bindings->length(); i++) {
|
| + const char* reference_name = collection_->names()->GetFormatted(
|
| + "bound_argument_%d",
|
| + i - JSFunction::kBoundArgumentsStartIndex);
|
| + SetNativeBindReference(js_obj, entry, reference_name,
|
| + bindings->get(i));
|
| + }
|
| + } else {
|
| // Add context allocated locals.
|
| int context_locals = scope_info->ContextLocalCount();
|
| for (int i = 0; i < context_locals; ++i) {
|
| @@ -2444,6 +2454,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,
|
|
|