From 2e1e5fc09c57c6fe7e692aa2cf68735e4518bda1 Mon Sep 17 00:00:00 2001 From: "mikhail.naganov@gmail.com" Date: Tue, 23 Aug 2011 12:24:54 +0000 Subject: [PATCH] Heap profiler: for objects of class "Object", try to lookup name from the constructor function. This works well for binding objects, and this matches DevTools' algorithm for name assignment. R=sgjesse@chromium.org BUG=none TEST=test-heap-profiler/GetConstructorName Review URL: http://codereview.chromium.org/7709026 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9000 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/profile-generator.cc | 36 +++++++++++++++----- src/profile-generator.h | 5 ++- test/cctest/test-heap-profiler.cc | 56 +++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/profile-generator.cc b/src/profile-generator.cc index 07426f293..db9f8928d 100644 --- a/src/profile-generator.cc +++ b/src/profile-generator.cc @@ -1663,7 +1663,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, } else if (object->IsJSGlobalObject()) { const char* tag = objects_tags_.GetTag(object); const char* name = collection_->names()->GetName( - GetConstructorNameForHeapProfile(JSObject::cast(object))); + GetConstructorName(JSObject::cast(object))); if (tag != NULL) { name = collection_->names()->GetFormatted("%s / %s", name, tag); } @@ -1691,8 +1691,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, return AddEntry(object, HeapEntry::kObject, collection_->names()->GetName( - GetConstructorNameForHeapProfile( - JSObject::cast(object))), + GetConstructorName(JSObject::cast(object))), children_count, retainers_count); } else if (object->IsString()) { @@ -2101,6 +2100,31 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj, } +String* V8HeapExplorer::GetConstructorName(JSObject* object) { + if (object->IsJSFunction()) return HEAP->closure_symbol(); + String* constructor_name = object->constructor_name(); + if (constructor_name == HEAP->Object_symbol()) { + // Look up an immediate "constructor" property, if it is a function, + // return its name. This is for instances of binding objects, which + // have prototype constructor type "Object". + Object* constructor_prop = NULL; + LookupResult result; + object->LocalLookupRealNamedProperty(HEAP->constructor_symbol(), &result); + if (result.IsProperty()) { + constructor_prop = result.GetLazyValue(); + } + if (constructor_prop->IsJSFunction()) { + Object* maybe_name = JSFunction::cast(constructor_prop)->shared()->name(); + if (maybe_name->IsString()) { + String* name = String::cast(maybe_name); + if (name->length() > 0) return name; + } + } + } + return object->constructor_name(); +} + + HeapEntry* V8HeapExplorer::GetEntry(Object* obj) { if (!obj->IsHeapObject()) return NULL; return filler_->FindOrAddEntry(obj, this); @@ -3250,10 +3274,4 @@ void HeapSnapshotJSONSerializer::SortHashMap( sorted_entries->Sort(SortUsingEntryValue); } - -String* GetConstructorNameForHeapProfile(JSObject* object) { - if (object->IsJSFunction()) return HEAP->closure_symbol(); - return object->constructor_name(); -} - } } // namespace v8::internal diff --git a/src/profile-generator.h b/src/profile-generator.h index d1c2b3804..9ab44a1e2 100644 --- a/src/profile-generator.h +++ b/src/profile-generator.h @@ -921,6 +921,8 @@ class V8HeapExplorer : public HeapEntriesAllocator { bool IterateAndExtractReferences(SnapshotFillerInterface* filler); void TagGlobalObjects(); + static String* GetConstructorName(JSObject* object); + static HeapObject* const kInternalRootObject; private: @@ -1119,9 +1121,6 @@ class HeapSnapshotJSONSerializer { DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer); }; - -String* GetConstructorNameForHeapProfile(JSObject* object); - } } // namespace v8::internal #endif // V8_PROFILE_GENERATOR_H_ diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc index 169e6dcbd..24d96193a 100644 --- a/test/cctest/test-heap-profiler.cc +++ b/test/cctest/test-heap-profiler.cc @@ -889,3 +889,59 @@ TEST(NodesIteration) { } CHECK_EQ(1, count); } + + +static int StringCmp(const char* ref, i::String* act) { + i::SmartPointer s_act = act->ToCString(); + int result = strcmp(ref, *s_act); + if (result != 0) + fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); + return result; +} + + +TEST(GetConstructorName) { + v8::HandleScope scope; + LocalContext env; + + CompileRun( + "function Constructor1() {};\n" + "var obj1 = new Constructor1();\n" + "var Constructor2 = function() {};\n" + "var obj2 = new Constructor2();\n" + "var obj3 = {};\n" + "obj3.constructor = function Constructor3() {};\n" + "var obj4 = {};\n" + "// Slow properties\n" + "for (var i=0; i<2000; ++i) obj4[\"p\" + i] = i;\n" + "obj4.constructor = function Constructor4() {};\n" + "var obj5 = {};\n" + "var obj6 = {};\n" + "obj6.constructor = 6;"); + v8::Local js_global = + env->Global()->GetPrototype().As(); + v8::Local obj1 = js_global->Get(v8_str("obj1")).As(); + i::Handle js_obj1 = v8::Utils::OpenHandle(*obj1); + CHECK_EQ(0, StringCmp( + "Constructor1", i::V8HeapExplorer::GetConstructorName(*js_obj1))); + v8::Local obj2 = js_global->Get(v8_str("obj2")).As(); + i::Handle js_obj2 = v8::Utils::OpenHandle(*obj2); + CHECK_EQ(0, StringCmp( + "Constructor2", i::V8HeapExplorer::GetConstructorName(*js_obj2))); + v8::Local obj3 = js_global->Get(v8_str("obj3")).As(); + i::Handle js_obj3 = v8::Utils::OpenHandle(*obj3); + CHECK_EQ(0, StringCmp( + "Constructor3", i::V8HeapExplorer::GetConstructorName(*js_obj3))); + v8::Local obj4 = js_global->Get(v8_str("obj4")).As(); + i::Handle js_obj4 = v8::Utils::OpenHandle(*obj4); + CHECK_EQ(0, StringCmp( + "Constructor4", i::V8HeapExplorer::GetConstructorName(*js_obj4))); + v8::Local obj5 = js_global->Get(v8_str("obj5")).As(); + i::Handle js_obj5 = v8::Utils::OpenHandle(*obj5); + CHECK_EQ(0, StringCmp( + "Object", i::V8HeapExplorer::GetConstructorName(*js_obj5))); + v8::Local obj6 = js_global->Get(v8_str("obj6")).As(); + i::Handle js_obj6 = v8::Utils::OpenHandle(*obj6); + CHECK_EQ(0, StringCmp( + "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); +} -- 2.34.1