| Index: runtime/vm/raw_object_snapshot.cc
|
| diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
|
| index eec25231efd802fd6b598fb917a80a67a9f7dd3f..730311eea452912beb0cdef73b867bb966ab055c 100644
|
| --- a/runtime/vm/raw_object_snapshot.cc
|
| +++ b/runtime/vm/raw_object_snapshot.cc
|
| @@ -644,13 +644,12 @@ void RawClosureData::WriteTo(SnapshotWriter* writer,
|
| // Context scope.
|
| if (ptr()->context_scope_ == Object::empty_context_scope().raw()) {
|
| writer->WriteVMIsolateObject(kEmptyContextScopeObject);
|
| + } else if (ptr()->context_scope_->ptr()->is_implicit_ ||
|
| + (kind == Snapshot::kAppWithJIT)) {
|
| + writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
|
| } else {
|
| - if (ptr()->context_scope_->ptr()->is_implicit_) {
|
| - writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
|
| - } else {
|
| - // We don't write non implicit context scopes in the snapshot.
|
| - writer->WriteVMIsolateObject(kNullObject);
|
| - }
|
| + // We don't write non implicit context scopes in the snapshot.
|
| + writer->WriteVMIsolateObject(kNullObject);
|
| }
|
|
|
| // Parent function.
|
| @@ -730,7 +729,7 @@ RawFunction* Function::ReadFrom(SnapshotReader* reader,
|
| func.set_kind_tag(reader->Read<uint32_t>());
|
| func.set_token_pos(TokenPosition::SnapshotDecode(token_pos));
|
| func.set_end_token_pos(TokenPosition::SnapshotDecode(end_token_pos));
|
| - if (Snapshot::IncludesCode(kind)) {
|
| + if (kind == Snapshot::kAppNoJIT) {
|
| func.set_usage_counter(0);
|
| func.set_deoptimization_counter(0);
|
| func.set_optimized_instruction_count(0);
|
| @@ -748,12 +747,23 @@ RawFunction* Function::ReadFrom(SnapshotReader* reader,
|
| func.raw()->from(), func.raw()->to_snapshot(),
|
| kAsReference);
|
| // Initialize all fields that are not part of the snapshot.
|
| - if (Snapshot::IncludesCode(kind)) {
|
| + if (kind == Snapshot::kAppNoJIT) {
|
| + // Read the code object and fixup entry point.
|
| func.ClearICDataArray();
|
| func.ClearCode();
|
| - // Read the code object and fixup entry point.
|
| (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
|
| func.SetInstructions(*reader->CodeHandle());
|
| + } else if (kind == Snapshot::kAppWithJIT) {
|
| + (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
|
| + func.set_ic_data_array(*reader->ArrayHandle());
|
| + (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
|
| + func.set_unoptimized_code(*reader->CodeHandle());
|
| + if (!reader->CodeHandle()->IsNull()) {
|
| + func.SetInstructions(*reader->CodeHandle());
|
| + func.set_was_compiled(true);
|
| + } else {
|
| + func.ClearCode();
|
| + }
|
| } else {
|
| bool is_optimized = func.usage_counter() != 0;
|
| if (is_optimized) {
|
| @@ -784,7 +794,7 @@ void RawFunction::WriteTo(SnapshotWriter* writer,
|
| intptr_t tags = writer->GetObjectTags(ptr()->owner_);
|
| intptr_t cid = ClassIdTag::decode(tags);
|
| owner_is_class = (cid == kClassCid);
|
| - is_in_fullsnapshot = owner_is_class ?
|
| + is_in_fullsnapshot = owner_is_class ?
|
| Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(ptr()->owner_)) :
|
| PatchClass::IsInFullSnapshot(
|
| reinterpret_cast<RawPatchClass*>(ptr()->owner_));
|
| @@ -811,7 +821,7 @@ void RawFunction::WriteTo(SnapshotWriter* writer,
|
| writer->Write<int16_t>(ptr()->num_fixed_parameters_);
|
| writer->Write<int16_t>(ptr()->num_optional_parameters_);
|
| writer->Write<uint32_t>(ptr()->kind_tag_);
|
| - if (Snapshot::IncludesCode(kind)) {
|
| + if (kind == Snapshot::kAppNoJIT) {
|
| // Omit fields used to support de/reoptimization.
|
| } else {
|
| if (is_optimized) {
|
| @@ -827,15 +837,16 @@ void RawFunction::WriteTo(SnapshotWriter* writer,
|
| // Write out all the object pointer fields.
|
| SnapshotWriterVisitor visitor(writer, kAsReference);
|
| visitor.VisitPointers(from(), to_snapshot());
|
| - if (Snapshot::IncludesCode(kind)) {
|
| + if (kind == Snapshot::kAppNoJIT) {
|
| ASSERT(ptr()->ic_data_array_ == Array::null());
|
| ASSERT((ptr()->code_ == ptr()->unoptimized_code_) ||
|
| (ptr()->unoptimized_code_ == Code::null()));
|
| - // Write out the code object as we are generating a precompiled snapshot.
|
| writer->WriteObjectImpl(ptr()->code_, kAsInlinedObject);
|
| + } else if (kind == Snapshot::kAppWithJIT) {
|
| + writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
|
| + writer->WriteObjectImpl(ptr()->unoptimized_code_, kAsInlinedObject);
|
| } else if (is_optimized) {
|
| - // Write out the ic data array as the function is optimized or
|
| - // we are generating a precompiled snapshot.
|
| + // Write out the ic data array as the function is optimized.
|
| writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
|
| }
|
| } else {
|
| @@ -922,6 +933,9 @@ void RawField::WriteTo(SnapshotWriter* writer,
|
| // For precompiled static fields, the value was already reset and
|
| // initializer_ now contains a Function.
|
| writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
|
| + } else if (Field::ConstBit::decode(ptr()->kind_bits_)) {
|
| + // Do not reset const fields.
|
| + writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
|
| } else {
|
| // Otherwise, for static fields we write out the initial static value.
|
| writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
|
| @@ -1436,9 +1450,21 @@ void RawCode::WriteTo(SnapshotWriter* writer,
|
| intptr_t pointer_offsets_length =
|
| Code::PtrOffBits::decode(ptr()->state_bits_);
|
| if (pointer_offsets_length != 0) {
|
| - // Should only be IA32.
|
| FATAL("Cannot serialize code with embedded pointers");
|
| }
|
| + if (kind == Snapshot::kAppNoJIT) {
|
| + // No disabled code in precompilation.
|
| + ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
|
| + } else {
|
| + ASSERT(kind == Snapshot::kAppWithJIT);
|
| + // We never include optimized code in JIT precompilation. Deoptimization
|
| + // requires code patching and we cannot patch code that is shared between
|
| + // isolates and should not mutate memory allocated by the embedder.
|
| + bool is_optimized = Code::PtrOffBits::decode(ptr()->state_bits_);
|
| + if (is_optimized) {
|
| + FATAL("Cannot include optimized code in a JIT snapshot");
|
| + }
|
| + }
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteInlinedObjectHeader(object_id);
|
| @@ -1450,9 +1476,6 @@ void RawCode::WriteTo(SnapshotWriter* writer,
|
| // Write out all the non object fields.
|
| writer->Write<int32_t>(ptr()->state_bits_);
|
|
|
| - // No disabled code in precompilation.
|
| - ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
|
| -
|
| RawInstructions* instr = ptr()->instructions_;
|
| int32_t text_offset = writer->GetInstructionsId(instr, this);
|
| writer->Write<int32_t>(text_offset);
|
| @@ -1912,7 +1935,7 @@ RawContextScope* ContextScope::ReadFrom(SnapshotReader* reader,
|
| // Allocate context object.
|
| bool is_implicit = reader->Read<bool>();
|
| if (is_implicit) {
|
| - ContextScope& context_scope = ContextScope::ZoneHandle();
|
| + ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
|
| if (Snapshot::IsFull(kind)) {
|
| context_scope = reader->NewContextScope(1);
|
| context_scope.set_is_implicit(true);
|
| @@ -1932,6 +1955,19 @@ RawContextScope* ContextScope::ReadFrom(SnapshotReader* reader,
|
| context_scope.SetContextIndexAt(0, 0);
|
| context_scope.SetContextLevelAt(0, 0);
|
| return context_scope.raw();
|
| + } else if (kind == Snapshot::kAppWithJIT) {
|
| + int32_t num_vars = reader->Read<int32_t>();
|
| +
|
| + ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
|
| + context_scope = reader->NewContextScope(num_vars);
|
| + context_scope.set_is_implicit(false);
|
| + reader->AddBackRef(object_id, &context_scope, kIsDeserialized);
|
| +
|
| + READ_OBJECT_FIELDS(context_scope,
|
| + context_scope.raw()->from(),
|
| + context_scope.raw()->to(num_vars),
|
| + kAsInlinedObject);
|
| + return context_scope.raw();
|
| }
|
| UNREACHABLE();
|
| return NULL;
|
| @@ -1962,6 +1998,23 @@ void RawContextScope::WriteTo(SnapshotWriter* writer,
|
| writer->WriteObjectImpl(var->type, kAsInlinedObject);
|
|
|
| return;
|
| + } else if (kind == Snapshot::kAppWithJIT) {
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteVMIsolateObject(kContextScopeCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out is_implicit flag for the context scope.
|
| + writer->Write<bool>(false);
|
| + int32_t num_vars = ptr()->num_variables_;
|
| + writer->Write<int32_t>(num_vars);
|
| +
|
| + SnapshotWriterVisitor visitor(writer, kAsInlinedObject);
|
| + visitor.VisitPointers(from(), to(num_vars));
|
| +
|
| + return;
|
| }
|
| UNREACHABLE();
|
| }
|
|
|