diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc index d65b814003..cb1fa4d58d 100644 --- a/src/heap-snapshot-generator.cc +++ b/src/heap-snapshot-generator.cc @@ -955,9 +955,10 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) { ExtractCellReferences(entry, Cell::cast(obj)); extract_indexed_refs = false; } else if (obj->IsPropertyCell()) { - ExtractPropertyCellReferences( - entry, PropertyCell::cast(obj)); + ExtractPropertyCellReferences(entry, PropertyCell::cast(obj)); extract_indexed_refs = false; + } else if (obj->IsAllocationSite()) { + ExtractAllocationSiteReferences(entry, AllocationSite::cast(obj)); } if (extract_indexed_refs) { SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); @@ -1264,6 +1265,13 @@ void V8HeapExplorer::ExtractPropertyCellReferences(int entry, } +void V8HeapExplorer::ExtractAllocationSiteReferences(int entry, + AllocationSite* site) { + SetInternalReference(site, entry, "transition_info", site->transition_info(), + AllocationSite::kTransitionInfoOffset); +} + + void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { if (!js_obj->IsJSFunction()) return; diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h index 70881ef642..31d808856d 100644 --- a/src/heap-snapshot-generator.h +++ b/src/heap-snapshot-generator.h @@ -460,6 +460,7 @@ class V8HeapExplorer : public HeapEntriesAllocator { void ExtractCodeReferences(int entry, Code* code); void ExtractCellReferences(int entry, Cell* cell); void ExtractPropertyCellReferences(int entry, PropertyCell* cell); + void ExtractAllocationSiteReferences(int entry, AllocationSite* site); void ExtractClosureReferences(JSObject* js_obj, int entry); void ExtractPropertyReferences(JSObject* js_obj, int entry); bool ExtractAccessorPairProperty(JSObject* js_obj, int entry, diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc index ba6a97a4c6..7d5de8d047 100644 --- a/test/cctest/test-heap-profiler.cc +++ b/test/cctest/test-heap-profiler.cc @@ -1832,3 +1832,53 @@ TEST(ManyLocalsInSharedContext) { CHECK_NE(NULL, f_object); } } + + +TEST(AllocationSitesAreVisible) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + CompileRun( + "fun = function () { var a = [3, 2, 1]; return a; }\n" + "fun();"); + const v8::HeapSnapshot* snapshot = + heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); + + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + CHECK_NE(NULL, global); + const v8::HeapGraphNode* fun_code = + GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); + CHECK_NE(NULL, fun_code); + const v8::HeapGraphNode* literals = + GetProperty(fun_code, v8::HeapGraphEdge::kInternal, "literals"); + CHECK_NE(NULL, literals); + CHECK_EQ(v8::HeapGraphNode::kArray, literals->GetType()); + CHECK_EQ(2, literals->GetChildrenCount()); + + // The second value in the literals array should be the boilerplate, + // after an AllocationSite. + const v8::HeapGraphEdge* prop = literals->GetChild(1); + const v8::HeapGraphNode* allocation_site = prop->GetToNode(); + v8::String::Utf8Value name(allocation_site->GetName()); + CHECK_EQ("system / AllocationSite", *name); + const v8::HeapGraphNode* transition_info = + GetProperty(allocation_site, v8::HeapGraphEdge::kInternal, + "transition_info"); + CHECK_NE(NULL, transition_info); + + const v8::HeapGraphNode* elements = + GetProperty(transition_info, v8::HeapGraphEdge::kInternal, + "elements"); + CHECK_NE(NULL, elements); + CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); + CHECK_EQ(v8::internal::FixedArray::SizeFor(3), elements->GetSelfSize()); + + CHECK(transition_info->GetHeapValue()->IsArray()); + v8::Handle array = v8::Handle::Cast( + transition_info->GetHeapValue()); + // Verify the array is "a" in the code above. + CHECK_EQ(3, array->Length()); + CHECK_EQ(v8::Integer::New(3), array->Get(v8::Integer::New(0))); + CHECK_EQ(v8::Integer::New(2), array->Get(v8::Integer::New(1))); + CHECK_EQ(v8::Integer::New(1), array->Get(v8::Integer::New(2))); +}