Chromium Code Reviews| Index: test/cctest/test-serialize.cc |
| diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc |
| index 350cba8b365078b5a8689f92d3ff16d774e449a3..ed251f2c01de033eb0e66d90ef26f76676c0d2f2 100644 |
| --- a/test/cctest/test-serialize.cc |
| +++ b/test/cctest/test-serialize.cc |
| @@ -1126,6 +1126,101 @@ TEST(CodeSerializerLargeCodeObject) { |
| source.Dispose(); |
| } |
| +TEST(CodeSerializerLargeCodeObjectWithIncrementalMarking) { |
| + FLAG_serialize_toplevel = true; |
| + FLAG_always_opt = false; |
| + // This test relies on (full-codegen) code objects going to large object |
| + // space. Once FCG goes away, it must either be redesigned (to put some |
| + // other large deserialized object into LO space), or it can be deleted. |
| + FLAG_ignition = false; |
| + FLAG_turbo_filter = "NOTHING"; |
| + FLAG_black_allocation = true; |
| + FLAG_manual_evacuation_candidates_selection = true; |
| + |
| + LocalContext context; |
| + Isolate* isolate = CcTest::i_isolate(); |
| + Heap* heap = isolate->heap(); |
| + isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. |
| + |
| + v8::HandleScope scope(CcTest::isolate()); |
| + |
| + Vector<const uint8_t> source = ConstructSource( |
| + STATIC_CHAR_VECTOR("var j=1; if (j == 0) {"), |
| + STATIC_CHAR_VECTOR("for (var i = 0; i < Object.prototype; i++);"), |
| + STATIC_CHAR_VECTOR("} j=7; var s = 'happy_hippo'; j"), 1400); |
| + Handle<String> source_str = |
| + isolate->factory()->NewStringFromOneByte(source).ToHandleChecked(); |
| + |
| + // Create a string on an evacuation candidate in old space. |
| + Handle<String> moving_object; |
| + Page* ec_page; |
| + { |
| + AlwaysAllocateScope always_allocate(isolate); |
| + heap::SimulateFullSpace(heap->old_space()); |
| + moving_object = isolate->factory()->InternalizeString( |
| + isolate->factory()->NewStringFromAsciiChecked("happy_hippo")); |
| + ec_page = Page::FromAddress(moving_object->address()); |
| + } |
| + |
| + Handle<JSObject> global(isolate->context()->global_object()); |
| + ScriptData* cache = NULL; |
| + |
| + Handle<SharedFunctionInfo> orig = |
| + CompileScript(isolate, source_str, Handle<String>(), &cache, |
| + v8::ScriptCompiler::kProduceCodeCache); |
| + |
| + CHECK(heap->InSpace(orig->abstract_code(), LO_SPACE)); |
| + |
| + // Pretend that incremental marking is on when deserialization begins. |
| + heap::ForceEvacuationCandidate(ec_page); |
| + MarkCompactCollector* collector = heap->mark_compact_collector(); |
| + IncrementalMarking* marking = heap->incremental_marking(); |
|
Michael Lippautz
2017/05/09 18:27:44
I think you can use
heap::SimulateIncrementalMar
Jakob Kummerow
2017/05/10 11:09:07
Done.
|
| + if (collector->sweeping_in_progress()) { |
| + collector->EnsureSweepingCompleted(); |
| + } |
| + CHECK(marking->IsMarking() || marking->IsStopped()); |
| + if (marking->IsStopped()) { |
| + heap->StartIncrementalMarking(Heap::kNoGCFlags, |
| + GarbageCollectionReason::kTesting); |
| + } |
| + CHECK(marking->IsMarking()); |
| + marking->StartBlackAllocationForTesting(); |
| + CHECK(marking->IsCompacting()); |
| + CHECK(MarkCompactCollector::IsOnEvacuationCandidate(*moving_object)); |
| + |
| + Handle<SharedFunctionInfo> copy; |
| + { |
| + DisallowCompilation no_compile_expected(isolate); |
| + copy = CompileScript(isolate, source_str, Handle<String>(), &cache, |
| + v8::ScriptCompiler::kConsumeCodeCache); |
| + } |
| + CHECK_NE(*orig, *copy); |
| + |
| + // We should have missed a write barrier. Complete incremental marking |
| + // to flush out the bug. |
| + while (!marking->IsComplete()) { |
|
Michael Lippautz
2017/05/09 18:27:44
I think you can use
heap::SimulateIncrementalMar
Jakob Kummerow
2017/05/10 11:09:07
Done.
|
| + marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD, |
| + IncrementalMarking::FORCE_COMPLETION, StepOrigin::kV8); |
| + if (marking->IsReadyToOverApproximateWeakClosure()) { |
| + marking->FinalizeIncrementally(); |
| + } |
| + } |
| + CcTest::CollectAllGarbage(); |
| + |
| + Handle<JSFunction> copy_fun = |
| + isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| + copy, isolate->native_context()); |
| + |
| + Handle<Object> copy_result = |
| + Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked(); |
| + |
| + int result_int; |
| + CHECK(copy_result->ToInt32(&result_int)); |
| + CHECK_EQ(7, result_int); |
| + |
| + delete cache; |
| + source.Dispose(); |
| +} |
| TEST(CodeSerializerLargeStrings) { |
| FLAG_serialize_toplevel = true; |
| LocalContext context; |