 Chromium Code Reviews
 Chromium Code Reviews Issue 2868103002:
  [deserializer] Make large object deserialization GC safe  (Closed)
    
  
    Issue 2868103002:
  [deserializer] Make large object deserialization GC safe  (Closed) 
  | 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; |