From ec8f9761131012f4cdba73383d7b472d31546a9d Mon Sep 17 00:00:00 2001 From: "alph@chromium.org" Date: Thu, 11 Sep 2014 11:08:40 +0000 Subject: [PATCH] Add AccessorInfo handling into heap profiler. BUG= R=svenpanne@chromium.org, yurys@chromium.org Review URL: https://codereview.chromium.org/564433003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23866 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/heap-snapshot-generator.cc | 31 ++++++++++++++++++++++++ src/heap-snapshot-generator.h | 1 + test/cctest/test-heap-profiler.cc | 40 +++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc index c328703197..cb9edaf2b4 100644 --- a/src/heap-snapshot-generator.cc +++ b/src/heap-snapshot-generator.cc @@ -1118,6 +1118,8 @@ bool V8HeapExplorer::ExtractReferencesPass1(int entry, HeapObject* obj) { ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj)); } else if (obj->IsScript()) { ExtractScriptReferences(entry, Script::cast(obj)); + } else if (obj->IsAccessorInfo()) { + ExtractAccessorInfoReferences(entry, AccessorInfo::cast(obj)); } else if (obj->IsAccessorPair()) { ExtractAccessorPairReferences(entry, AccessorPair::cast(obj)); } else if (obj->IsCodeCache()) { @@ -1469,6 +1471,35 @@ void V8HeapExplorer::ExtractScriptReferences(int entry, Script* script) { } +void V8HeapExplorer::ExtractAccessorInfoReferences( + int entry, AccessorInfo* accessor_info) { + SetInternalReference(accessor_info, entry, "name", accessor_info->name(), + AccessorInfo::kNameOffset); + SetInternalReference(accessor_info, entry, "expected_receiver_type", + accessor_info->expected_receiver_type(), + AccessorInfo::kExpectedReceiverTypeOffset); + if (accessor_info->IsDeclaredAccessorInfo()) { + DeclaredAccessorInfo* declared_accessor_info = + DeclaredAccessorInfo::cast(accessor_info); + SetInternalReference(declared_accessor_info, entry, "descriptor", + declared_accessor_info->descriptor(), + DeclaredAccessorInfo::kDescriptorOffset); + } else if (accessor_info->IsExecutableAccessorInfo()) { + ExecutableAccessorInfo* executable_accessor_info = + ExecutableAccessorInfo::cast(accessor_info); + SetInternalReference(executable_accessor_info, entry, "getter", + executable_accessor_info->getter(), + ExecutableAccessorInfo::kGetterOffset); + SetInternalReference(executable_accessor_info, entry, "setter", + executable_accessor_info->setter(), + ExecutableAccessorInfo::kSetterOffset); + SetInternalReference(executable_accessor_info, entry, "data", + executable_accessor_info->data(), + ExecutableAccessorInfo::kDataOffset); + } +} + + void V8HeapExplorer::ExtractAccessorPairReferences( int entry, AccessorPair* accessors) { SetInternalReference(accessors, entry, "getter", accessors->getter(), diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h index 1aea5a0264..a0d73bfaec 100644 --- a/src/heap-snapshot-generator.h +++ b/src/heap-snapshot-generator.h @@ -378,6 +378,7 @@ class V8HeapExplorer : public HeapEntriesAllocator { void ExtractSharedFunctionInfoReferences(int entry, SharedFunctionInfo* shared); void ExtractScriptReferences(int entry, Script* script); + void ExtractAccessorInfoReferences(int entry, AccessorInfo* accessor_info); void ExtractAccessorPairReferences(int entry, AccessorPair* accessors); void ExtractCodeCacheReferences(int entry, CodeCache* code_cache); void ExtractCodeReferences(int entry, Code* code); diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc index 10ea60daa3..80f0279289 100644 --- a/test/cctest/test-heap-profiler.cc +++ b/test/cctest/test-heap-profiler.cc @@ -1987,6 +1987,46 @@ TEST(HiddenPropertiesFastCase) { } +TEST(AccessorInfo) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + + CompileRun("function foo(x) { }\n"); + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("AccessorInfoTest")); + CHECK(ValidateSnapshot(snapshot)); + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + const v8::HeapGraphNode* foo = + GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); + CHECK_NE(NULL, foo); + const v8::HeapGraphNode* map = + GetProperty(foo, v8::HeapGraphEdge::kInternal, "map"); + CHECK_NE(NULL, map); + const v8::HeapGraphNode* descriptors = + GetProperty(map, v8::HeapGraphEdge::kInternal, "descriptors"); + CHECK_NE(NULL, descriptors); + const v8::HeapGraphNode* length_name = + GetProperty(descriptors, v8::HeapGraphEdge::kInternal, "2"); + CHECK_NE(NULL, length_name); + CHECK_EQ("length", *v8::String::Utf8Value(length_name->GetName())); + const v8::HeapGraphNode* length_accessor = + GetProperty(descriptors, v8::HeapGraphEdge::kInternal, "4"); + CHECK_NE(NULL, length_accessor); + CHECK_EQ("system / ExecutableAccessorInfo", + *v8::String::Utf8Value(length_accessor->GetName())); + const v8::HeapGraphNode* name = + GetProperty(length_accessor, v8::HeapGraphEdge::kInternal, "name"); + CHECK_NE(NULL, name); + const v8::HeapGraphNode* getter = + GetProperty(length_accessor, v8::HeapGraphEdge::kInternal, "getter"); + CHECK_NE(NULL, getter); + const v8::HeapGraphNode* setter = + GetProperty(length_accessor, v8::HeapGraphEdge::kInternal, "setter"); + CHECK_NE(NULL, setter); +} + + bool HasWeakEdge(const v8::HeapGraphNode* node) { for (int i = 0; i < node->GetChildrenCount(); ++i) { const v8::HeapGraphEdge* handle_edge = node->GetChild(i);