Commit 7a1deffb authored by ahaas's avatar ahaas Committed by Commit bot

[serializer][heap] Record references in deserialized code objects.

References in code objects to new-space embedded objects have to be
recorded in a remembered set so that they get updated by the garbage
collector.

TEST=cctest/test-serialize/CodeSerializerEmbeddedObject

R=ulan@chromium.org, yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2200333004
Cr-Commit-Position: refs/heads/master@{#38335}
parent 9ab456d6
...@@ -37,9 +37,12 @@ void Deserializer::FlushICacheForNewIsolate() { ...@@ -37,9 +37,12 @@ void Deserializer::FlushICacheForNewIsolate() {
} }
} }
void Deserializer::FlushICacheForNewCodeObjects() { void Deserializer::FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects() {
DCHECK(deserializing_user_code_); DCHECK(deserializing_user_code_);
for (Code* code : new_code_objects_) { for (Code* code : new_code_objects_) {
// Record all references to embedded objects in the new code object.
isolate_->heap()->RecordWritesIntoCode(code);
if (FLAG_serialize_age_code) code->PreAge(isolate_); if (FLAG_serialize_age_code) code->PreAge(isolate_);
Assembler::FlushICache(isolate_, code->instruction_start(), Assembler::FlushICache(isolate_, code->instruction_start(),
code->instruction_size()); code->instruction_size());
...@@ -147,7 +150,7 @@ MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( ...@@ -147,7 +150,7 @@ MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode(
Object* root; Object* root;
VisitPointer(&root); VisitPointer(&root);
DeserializeDeferredObjects(); DeserializeDeferredObjects();
FlushICacheForNewCodeObjects(); FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects();
result = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); result = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root));
isolate->heap()->RegisterReservationsForBlackAllocation(reservations_); isolate->heap()->RegisterReservationsForBlackAllocation(reservations_);
} }
......
...@@ -89,7 +89,7 @@ class Deserializer : public SerializerDeserializer { ...@@ -89,7 +89,7 @@ class Deserializer : public SerializerDeserializer {
void DeserializeDeferredObjects(); void DeserializeDeferredObjects();
void FlushICacheForNewIsolate(); void FlushICacheForNewIsolate();
void FlushICacheForNewCodeObjects(); void FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects();
void CommitPostProcessedObjects(Isolate* isolate); void CommitPostProcessedObjects(Isolate* isolate);
......
...@@ -1885,6 +1885,61 @@ TEST(CodeSerializerCell) { ...@@ -1885,6 +1885,61 @@ TEST(CodeSerializerCell) {
} }
#endif // V8_TARGET_ARCH_X64 #endif // V8_TARGET_ARCH_X64
TEST(CodeSerializerEmbeddedObject) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
Heap* heap = isolate->heap();
v8::HandleScope scope(CcTest::isolate());
size_t actual_size;
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
HandleScope handles(isolate);
MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
v8::internal::CodeObjectRequired::kYes);
assembler.enable_serializer();
Handle<Object> number = isolate->factory()->NewHeapNumber(0.3);
CHECK(isolate->heap()->InNewSpace(*number));
Handle<Code> code;
{
MacroAssembler* masm = &assembler;
masm->Push(number);
CodeDesc desc;
masm->GetCode(&desc);
code = isolate->factory()->NewCode(desc, Code::ComputeFlags(Code::FUNCTION),
masm->CodeObject());
code->set_has_reloc_info_for_serialization(true);
}
RelocIterator rit1(*code, RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT));
CHECK_EQ(*number, rit1.rinfo()->target_object());
Handle<String> source = isolate->factory()->empty_string();
Handle<SharedFunctionInfo> sfi =
isolate->factory()->NewSharedFunctionInfo(source, code, false);
ScriptData* script_data = CodeSerializer::Serialize(isolate, sfi, source);
Handle<SharedFunctionInfo> copy =
CodeSerializer::Deserialize(isolate, script_data, source)
.ToHandleChecked();
RelocIterator rit2(copy->code(),
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT));
CHECK(rit2.rinfo()->target_object()->IsHeapNumber());
CHECK_EQ(0.3, HeapNumber::cast(rit2.rinfo()->target_object())->value());
heap->CollectAllAvailableGarbage();
RelocIterator rit3(copy->code(),
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT));
CHECK(rit3.rinfo()->target_object()->IsHeapNumber());
CHECK_EQ(0.3, HeapNumber::cast(rit3.rinfo()->target_object())->value());
delete script_data;
}
TEST(SnapshotCreatorMultipleContexts) { TEST(SnapshotCreatorMultipleContexts) {
DisableTurbofan(); DisableTurbofan();
v8::StartupData blob; v8::StartupData blob;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment