| Index: test/cctest/test-serialize.cc
|
| diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
|
| index 350cba8b365078b5a8689f92d3ff16d774e449a3..058dd55d3cceae04d8cf22df9ff38fb973afbc79 100644
|
| --- a/test/cctest/test-serialize.cc
|
| +++ b/test/cctest/test-serialize.cc
|
| @@ -1126,6 +1126,87 @@ 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;
|
| + const char* filter_flag = "--turbo-filter=NOTHING";
|
| + FlagList::SetFlagsFromString(filter_flag, StrLength(filter_flag));
|
| + 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"), 2100);
|
| + 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);
|
| + heap::SimulateIncrementalMarking(heap, false);
|
| + IncrementalMarking* marking = heap->incremental_marking();
|
| + 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.
|
| + heap::SimulateIncrementalMarking(heap, true);
|
| + 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;
|
|
|