Index: test/cctest/test-heap.cc |
=================================================================== |
--- test/cctest/test-heap.cc (revision 10404) |
+++ test/cctest/test-heap.cc (working copy) |
@@ -1187,6 +1187,44 @@ |
} |
+TEST(TestSizeOfObjects) { |
+ v8::V8::Initialize(); |
+ |
+ // Get initial heap size after several full GCs, which will stabilize |
+ // the heap size and return with sweeping finished completely. |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ CHECK(HEAP->old_pointer_space()->IsSweepingComplete()); |
+ int initial_size = static_cast<int>(HEAP->SizeOfObjects()); |
+ |
+ { |
+ // Allocate objects on several different old-space pages so that |
+ // lazy sweeping kicks in for subsequent GC runs. |
+ AlwaysAllocateScope always_allocate; |
+ int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); |
+ for (int i = 1; i <= 100; i++) { |
+ HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked(); |
+ CHECK_EQ(initial_size + i * filler_size, |
+ static_cast<int>(HEAP->SizeOfObjects())); |
+ } |
+ } |
+ |
+ // The heap size should go back to initial size after a full GC, even |
+ // though sweeping didn't finish yet. |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ CHECK(!HEAP->old_pointer_space()->IsSweepingComplete()); |
+ CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); |
+ |
+ // Advancing the sweeper step-wise should not change the heap size. |
+ while (!HEAP->old_pointer_space()->IsSweepingComplete()) { |
+ HEAP->old_pointer_space()->AdvanceSweeper(KB); |
+ CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); |
+ } |
+} |
+ |
+ |
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { |
InitializeVM(); |
HEAP->EnsureHeapIsIterable(); |
@@ -1476,3 +1514,61 @@ |
HEAP->CollectAllAvailableGarbage(); |
CHECK_EQ(0, NumberOfGlobalObjects()); |
} |
+ |
+ |
+TEST(InstanceOfStubWriteBarrier) { |
+ i::FLAG_allow_natives_syntax = true; |
+#ifdef DEBUG |
+ i::FLAG_verify_heap = true; |
+#endif |
+ InitializeVM(); |
+ if (!i::V8::UseCrankshaft()) return; |
+ v8::HandleScope outer_scope; |
+ |
+ { |
+ v8::HandleScope scope; |
+ CompileRun( |
+ "function foo () { }" |
+ "function mkbar () { return new (new Function(\"\")) (); }" |
+ "function f (x) { return (x instanceof foo); }" |
+ "function g () { f(mkbar()); }" |
+ "f(new foo()); f(new foo());" |
+ "%OptimizeFunctionOnNextCall(f);" |
+ "f(new foo()); g();"); |
+ } |
+ |
+ IncrementalMarking* marking = HEAP->incremental_marking(); |
+ marking->Abort(); |
+ marking->Start(); |
+ |
+ Handle<JSFunction> f = |
+ v8::Utils::OpenHandle( |
+ *v8::Handle<v8::Function>::Cast( |
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
+ |
+ CHECK(f->IsOptimized()); |
+ |
+ while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && |
+ !marking->IsStopped()) { |
+ marking->Step(MB); |
+ } |
+ |
+ CHECK(marking->IsMarking()); |
+ |
+ // Discard any pending GC requests otherwise we will get GC when we enter |
+ // code below. |
+ if (ISOLATE->stack_guard()->IsGCRequest()) { |
+ ISOLATE->stack_guard()->Continue(GC_REQUEST); |
+ } |
+ |
+ { |
+ v8::HandleScope scope; |
+ v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global(); |
+ v8::Handle<v8::Function> g = |
+ v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); |
+ g->Call(global, 0, NULL); |
+ } |
+ |
+ HEAP->incremental_marking()->set_should_hurry(true); |
+ HEAP->CollectGarbage(OLD_POINTER_SPACE); |
+} |