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()) {
}
+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(),
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);
}
+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);