Index: test/cctest/test-heap.cc |
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc |
index 799146e7a5168a0f8d43acd6a891b2902cf651a5..a14e6495fb1a8227a25c46d0878380943255faf2 100644 |
--- a/test/cctest/test-heap.cc |
+++ b/test/cctest/test-heap.cc |
@@ -3549,3 +3549,69 @@ TEST(DisableInlineAllocation) { |
CcTest::heap()->EnableInlineAllocation(); |
CompileRun("run()"); |
} |
+ |
+ |
+static int AllocationSitesCount(Heap* heap) { |
+ int count = 0; |
+ for (Object* site = heap->allocation_sites_list(); |
+ !(site->IsUndefined()); |
+ site = AllocationSite::cast(site)->weak_next()) { |
+ count++; |
+ } |
+ return count; |
+} |
+ |
+ |
+TEST(EnsureAllocationSiteDependentCodesProcessed) { |
+ if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; |
+ i::FLAG_allow_natives_syntax = true; |
+ CcTest::InitializeVM(); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ v8::internal::Heap* heap = CcTest::heap(); |
+ GlobalHandles* global_handles = isolate->global_handles(); |
+ |
+ // The allocation site at the head of the list is ours. |
+ Handle<AllocationSite> site; |
+ { |
+ LocalContext context; |
+ v8::HandleScope scope(context->GetIsolate()); |
+ |
+ int count = AllocationSitesCount(heap); |
+ CompileRun("var bar = function() { return (new Array()); };" |
+ "var a = bar();" |
+ "bar();" |
+ "bar();"); |
+ |
+ // One allocation site should have been created. |
+ int new_count = AllocationSitesCount(heap); |
+ ASSERT(new_count == (count + 1)); |
+ site = Handle<AllocationSite>::cast( |
+ global_handles->Create( |
+ AllocationSite::cast(heap->allocation_sites_list()))); |
+ |
+ CompileRun("%OptimizeFunctionOnNextCall(bar); bar();"); |
+ |
+ DependentCode::GroupStartIndexes starts(site->dependent_code()); |
+ ASSERT(starts.number_of_entries() >= 1); |
+ int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); |
+ ASSERT(site->dependent_code()->is_code_at(index)); |
+ Code* function_bar = site->dependent_code()->code_at(index); |
+ Handle<JSFunction> bar_handle = |
+ v8::Utils::OpenHandle( |
+ *v8::Handle<v8::Function>::Cast( |
+ CcTest::global()->Get(v8_str("bar")))); |
+ ASSERT(bar_handle->code() == function_bar); |
+ } |
+ |
+ // Now make sure that a gc should get rid of the function, even though we |
+ // still have the allocation site alive. |
+ for (int i = 0; i < 4; i++) { |
+ heap->CollectAllGarbage(false); |
+ } |
+ |
+ // The site still exists because of our global handle, but the code is no |
+ // longer referred to by dependent_code(). |
+ DependentCode::GroupStartIndexes starts(site->dependent_code()); |
+ int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); |
+ ASSERT(!(site->dependent_code()->is_code_at(index))); |
+} |