| Index: runtime/vm/raw_object_snapshot.cc
|
| diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
|
| index 22267285c4d5958e34de6f06f19e00895f7a0933..da3c3a646719b30974de152695bc6150a87bc1f3 100644
|
| --- a/runtime/vm/raw_object_snapshot.cc
|
| +++ b/runtime/vm/raw_object_snapshot.cc
|
| @@ -692,7 +692,9 @@ RawFunction* Function::ReadFrom(SnapshotReader* reader,
|
| // Set all the object fields.
|
| // TODO(5411462): Need to assert No GC can happen here, even though
|
| // allocations may happen.
|
| - intptr_t num_flds = (func.raw()->to_snapshot() - func.raw()->from());
|
| + RawObject** toaddr = reader->snapshot_code() ? func.raw()->to()
|
| + : func.raw()->to_snapshot();
|
| + intptr_t num_flds = toaddr - func.raw()->from();
|
| intptr_t from_offset = OFFSET_OF_FROM(func);
|
| for (intptr_t i = 0; i <= num_flds; i++) {
|
| (*reader->PassiveObjectHandle()) =
|
| @@ -701,9 +703,11 @@ RawFunction* Function::ReadFrom(SnapshotReader* reader,
|
| reader->PassiveObjectHandle()->raw());
|
| }
|
|
|
| - // Initialize all fields that are not part of the snapshot.
|
| - func.ClearICDataArray();
|
| - func.ClearCode();
|
| + if (!reader->snapshot_code()) {
|
| + // Initialize all fields that are not part of the snapshot.
|
| + func.ClearICDataArray();
|
| + func.ClearCode();
|
| + }
|
| return func.raw();
|
| }
|
|
|
| @@ -734,7 +738,8 @@ void RawFunction::WriteTo(SnapshotWriter* writer,
|
|
|
| // Write out all the object pointer fields.
|
| SnapshotWriterVisitor visitor(writer);
|
| - visitor.VisitPointers(from(), to_snapshot());
|
| + visitor.VisitPointers(from(), writer->snapshot_code() ? to()
|
| + : to_snapshot());
|
| }
|
|
|
|
|
| @@ -1183,17 +1188,63 @@ RawCode* Code::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| - return Code::null();
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + Code& result = Code::ZoneHandle(reader->zone(), NEW_OBJECT_WITH_LEN(Code, 0));
|
| + reader->AddBackRef(object_id, &result, kIsDeserialized);
|
| +
|
| + result.set_compile_timestamp(reader->Read<int64_t>());
|
| + result.set_state_bits(reader->Read<int32_t>());
|
| + result.set_entry_patch_pc_offset(reader->Read<int32_t>());
|
| + result.set_patch_code_pc_offset(reader->Read<int32_t>());
|
| + result.set_lazy_deopt_pc_offset(reader->Read<int32_t>());
|
| +
|
| + // Set all the object fields.
|
| + // TODO(5411462): Need to assert No GC can happen here, even though
|
| + // allocations may happen.
|
| + intptr_t num_flds = (result.raw()->to() - result.raw()->from());
|
| + for (intptr_t i = 0; i <= num_flds; i++) {
|
| + (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
|
| + result.StorePointer((result.raw()->from() + i),
|
| + reader->PassiveObjectHandle()->raw());
|
| + }
|
| +
|
| + return result.raw();
|
| }
|
|
|
|
|
| void RawCode::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - // We have already checked for this and written a NULL object, hence we
|
| - // should not reach here.
|
| - UNREACHABLE();
|
| + ASSERT(writer->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + intptr_t pointer_offsets_length =
|
| + Code::PtrOffBits::decode(ptr()->state_bits_);
|
| + if (pointer_offsets_length != 0) {
|
| + // Should only be IA32.
|
| + FATAL("Serializing embedded pointer offsets unimplemented");
|
| + }
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteVMIsolateObject(kCodeCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out all the non object fields.
|
| + writer->Write<int64_t>(ptr()->compile_timestamp_);
|
| + writer->Write<int32_t>(ptr()->state_bits_);
|
| + writer->Write<int32_t>(ptr()->entry_patch_pc_offset_);
|
| + writer->Write<int32_t>(ptr()->patch_code_pc_offset_);
|
| + writer->Write<int32_t>(ptr()->lazy_deopt_pc_offset_);
|
| +
|
| + // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| + visitor.VisitPointers(from(), to());
|
| }
|
|
|
|
|
| @@ -1201,15 +1252,35 @@ RawInstructions* Instructions::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| - return Instructions::null();
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + intptr_t id = reader->Read<int32_t>();
|
| + Instructions& result =
|
| + Instructions::ZoneHandle(reader->zone(),
|
| + reader->GetInstructionsById(id));
|
| + reader->AddBackRef(object_id, &result, kIsDeserialized);
|
| + return result.raw();
|
| }
|
|
|
|
|
| void RawInstructions::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| + ASSERT(writer->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + {
|
| + // TODO(rmacnak): Drop after calling convention change.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| + writer->WriteVMIsolateObject(kInstructionsCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| + writer->WriteObjectImpl(ptr()->code_, kAsReference);
|
| + writer->WriteObjectImpl(ptr()->object_pool_, kAsReference);
|
| + }
|
| +
|
| + writer->Write<int32_t>(writer->GetInstructionsId(this));
|
| }
|
|
|
|
|
| @@ -1217,15 +1288,90 @@ RawObjectPool* ObjectPool::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| - return ObjectPool::null();
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + intptr_t length = reader->Read<intptr_t>();
|
| +
|
| + ObjectPool& result =
|
| + ObjectPool::ZoneHandle(reader->zone(),
|
| + NEW_OBJECT_WITH_LEN(ObjectPool, length));
|
| + reader->AddBackRef(object_id, &result, kIsDeserialized);
|
| +
|
| + RawTypedData* info_array = result.raw_ptr()->info_array_->ptr();
|
| +
|
| + // Set all the object fields.
|
| + // TODO(5411462): Need to assert No GC can happen here, even though
|
| + // allocations may happen.
|
| + for (intptr_t i = 0; i < length; i++) {
|
| + ObjectPool::EntryType entry_type =
|
| + static_cast<ObjectPool::EntryType>(reader->Read<uint8_t>());
|
| + info_array->data()[i] = entry_type;
|
| + switch (entry_type) {
|
| + case ObjectPool::kTaggedObject: {
|
| + (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
|
| + result.SetObjectAt(i, *(reader->PassiveObjectHandle()));
|
| + break;
|
| + }
|
| + case ObjectPool::kImmediate: {
|
| + intptr_t raw_value = reader->Read<intptr_t>();
|
| + result.SetRawValueAt(i, raw_value);
|
| + break;
|
| + }
|
| + case ObjectPool::kExternalLabel: {
|
| + // TODO(rmacnak): Relocate.
|
| + intptr_t raw_value = reader->Read<intptr_t>();
|
| + result.SetRawValueAt(i, raw_value);
|
| + break;
|
| + }
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + }
|
| +
|
| + return result.raw();
|
| }
|
|
|
|
|
| void RawObjectPool::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| + ASSERT(writer->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteVMIsolateObject(kObjectPoolCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + intptr_t length = ptr()->length_;
|
| + RawTypedData* info_array = ptr()->info_array_->ptr();
|
| + ASSERT(info_array != TypedData::null());
|
| +
|
| + writer->Write<intptr_t>(length);
|
| + for (intptr_t i = 0; i < length; i++) {
|
| + ObjectPool::EntryType entry_type =
|
| + static_cast<ObjectPool::EntryType>(info_array->data()[i]);
|
| + writer->Write<uint8_t>(entry_type);
|
| + Entry& entry = ptr()->data()[i];
|
| + switch (entry_type) {
|
| + case ObjectPool::kTaggedObject:
|
| + writer->WriteObjectImpl(entry.raw_obj_, kAsReference);
|
| + break;
|
| + case ObjectPool::kImmediate:
|
| + writer->Write<intptr_t>(entry.raw_value_);
|
| + break;
|
| + case ObjectPool::kExternalLabel:
|
| + // TODO(rmacnak): Write symbolically.
|
| + writer->Write<intptr_t>(entry.raw_value_);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -1233,7 +1379,8 @@ RawPcDescriptors* PcDescriptors::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - ASSERT(reader->allow_code());
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
|
|
| const int32_t length = reader->Read<int32_t>();
|
| PcDescriptors& result = PcDescriptors::ZoneHandle(reader->zone(),
|
| @@ -1254,7 +1401,7 @@ RawPcDescriptors* PcDescriptors::ReadFrom(SnapshotReader* reader,
|
| void RawPcDescriptors::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - ASSERT(writer->allow_code());
|
| + ASSERT(writer->snapshot_code());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteInlinedObjectHeader(object_id);
|
| @@ -1273,7 +1420,8 @@ RawStackmap* Stackmap::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - ASSERT(reader->allow_code());
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
|
|
| const int32_t length = reader->Read<int32_t>();
|
| const int32_t register_bit_count = reader->Read<int32_t>();
|
| @@ -1298,7 +1446,7 @@ RawStackmap* Stackmap::ReadFrom(SnapshotReader* reader,
|
| void RawStackmap::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - ASSERT(writer->allow_code());
|
| + ASSERT(writer->snapshot_code());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteInlinedObjectHeader(object_id);
|
| @@ -1319,7 +1467,8 @@ RawLocalVarDescriptors* LocalVarDescriptors::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - ASSERT(reader->allow_code());
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
|
|
| const int32_t num_entries = reader->Read<int32_t>();
|
|
|
| @@ -1349,7 +1498,7 @@ RawLocalVarDescriptors* LocalVarDescriptors::ReadFrom(SnapshotReader* reader,
|
| void RawLocalVarDescriptors::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - ASSERT(writer->allow_code());
|
| + ASSERT(writer->snapshot_code());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteInlinedObjectHeader(object_id);
|
| @@ -1371,7 +1520,8 @@ RawExceptionHandlers* ExceptionHandlers::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - ASSERT(reader->allow_code());
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
|
|
| // handled_types_data.
|
| *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
|
| @@ -1397,7 +1547,7 @@ RawExceptionHandlers* ExceptionHandlers::ReadFrom(SnapshotReader* reader,
|
| void RawExceptionHandlers::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - ASSERT(writer->allow_code());
|
| + ASSERT(writer->snapshot_code());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteInlinedObjectHeader(object_id);
|
| @@ -1485,15 +1635,50 @@ RawICData* ICData::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| - return NULL;
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + ICData& result = ICData::ZoneHandle(reader->zone(), NEW_OBJECT(ICData));
|
| + reader->AddBackRef(object_id, &result, kIsDeserialized);
|
| +
|
| + result.set_deopt_id(reader->Read<int32_t>());
|
| + result.set_state_bits(reader->Read<uint32_t>());
|
| +
|
| + // Set all the object fields.
|
| + // TODO(5411462): Need to assert No GC can happen here, even though
|
| + // allocations may happen.
|
| + intptr_t num_flds = (result.raw()->to() - result.raw()->from());
|
| + for (intptr_t i = 0; i <= num_flds; i++) {
|
| + (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
|
| + result.StorePointer((result.raw()->from() + i),
|
| + reader->PassiveObjectHandle()->raw());
|
| + }
|
| +
|
| + return result.raw();
|
| }
|
|
|
|
|
| void RawICData::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| + ASSERT(writer->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteVMIsolateObject(kICDataCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out all the non object fields.
|
| + writer->Write<int32_t>(ptr()->deopt_id_);
|
| + writer->Write<uint32_t>(ptr()->state_bits_);
|
| +
|
| + // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| + visitor.VisitPointers(from(), to());
|
| }
|
|
|
|
|
| @@ -1501,15 +1686,50 @@ RawMegamorphicCache* MegamorphicCache::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| - return NULL;
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + MegamorphicCache& result =
|
| + MegamorphicCache::ZoneHandle(reader->zone(),
|
| + NEW_OBJECT(MegamorphicCache));
|
| + reader->AddBackRef(object_id, &result, kIsDeserialized);
|
| +
|
| + result.set_filled_entry_count(reader->Read<int32_t>());
|
| +
|
| + // Set all the object fields.
|
| + // TODO(5411462): Need to assert No GC can happen here, even though
|
| + // allocations may happen.
|
| + intptr_t num_flds = (result.raw()->to() - result.raw()->from());
|
| + for (intptr_t i = 0; i <= num_flds; i++) {
|
| + (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
|
| + result.StorePointer((result.raw()->from() + i),
|
| + reader->PassiveObjectHandle()->raw());
|
| + }
|
| +
|
| + return result.raw();
|
| }
|
|
|
|
|
| void RawMegamorphicCache::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| + ASSERT(writer->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteVMIsolateObject(kMegamorphicCacheCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out all the non object fields.
|
| + writer->Write<int32_t>(ptr()->filled_entry_count_);
|
| +
|
| + // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| + visitor.VisitPointers(from(), to());
|
| }
|
|
|
|
|
| @@ -1517,15 +1737,41 @@ RawSubtypeTestCache* SubtypeTestCache::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| - return NULL;
|
| + UNREACHABLE(); // Untested.
|
| + ASSERT(reader->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + SubtypeTestCache& result =
|
| + SubtypeTestCache::ZoneHandle(reader->zone(),
|
| + NEW_OBJECT(SubtypeTestCache));
|
| + reader->AddBackRef(object_id, &result, kIsDeserialized);
|
| +
|
| + // Set all the object fields.
|
| + // TODO(5411462): Need to assert No GC can happen here, even though
|
| + // allocations may happen.
|
| + (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
|
| + result.StorePointer(&result.raw_ptr()->cache_,
|
| + reader->ArrayHandle()->raw());
|
| +
|
| + return result.raw();
|
| }
|
|
|
|
|
| void RawSubtypeTestCache::WriteTo(SnapshotWriter* writer,
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| - UNREACHABLE();
|
| + ASSERT(writer->snapshot_code());
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteVMIsolateObject(kSubtypeTestCacheCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out all the object pointer fields.
|
| + writer->WriteObjectImpl(ptr()->cache_, kAsReference);
|
| }
|
|
|
|
|
|
|