Chromium Code Reviews| Index: runtime/vm/raw_object_snapshot.cc |
| diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc |
| index 0cff97ae8bf3ad8655741d355a685a156a283dd2..5d64f2505da20566937df1becd3f9be5c94f2016 100644 |
| --- a/runtime/vm/raw_object_snapshot.cc |
| +++ b/runtime/vm/raw_object_snapshot.cc |
| @@ -693,7 +693,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** to = reader->snapshot_code() ? func.raw()->to() |
|
siva
2015/08/19 19:40:03
maybe use a different name instead of 'to' say 'to
rmacnak
2015/08/19 22:33:54
Done.
|
| + : func.raw()->to_snapshot(); |
| + intptr_t num_flds = to - func.raw()->from(); |
|
Florian Schneider
2015/08/18 11:54:14
This loop setting all the fields seems to be dupli
rmacnak
2015/08/19 22:33:54
Good point, we have a helper for the write. Will p
|
| intptr_t from_offset = OFFSET_OF_FROM(func); |
| for (intptr_t i = 0; i <= num_flds; i++) { |
| (*reader->PassiveObjectHandle()) = |
| @@ -702,9 +704,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(); |
| } |
| @@ -736,7 +740,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()); |
| } |
| @@ -1185,17 +1190,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); |
| + |
| + // 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_); |
| + |
| + 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"); |
| + } |
|
siva
2015/08/19 19:40:02
Why not do this check on top before writing anythi
rmacnak
2015/08/19 22:33:54
Moved up.
|
| + |
| + // Write out all the object pointer fields. |
| + SnapshotWriterVisitor visitor(writer); |
| + visitor.VisitPointers(from(), to()); |
| } |
| @@ -1203,15 +1254,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); |
| + } |
|
siva
2015/08/19 19:40:02
Why is this scoped like this.
rmacnak
2015/08/19 22:33:54
Scoping the comment.
|
| + |
| + writer->Write<int32_t>(writer->GetInstructionsId(this)); |
| } |
| @@ -1219,15 +1290,80 @@ 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; |
| + } |
|
siva
2015/08/19 19:40:03
case statements seem to be not indented.
rmacnak
2015/08/19 22:33:54
Done.
|
| + default: |
| + UNREACHABLE(); |
|
siva
2015/08/19 19:40:02
It is probably better to throw exceptions in these
rmacnak
2015/08/19 22:33:54
Acknowledged.
|
| + } |
| + } |
| + |
| + 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; |
| + default: |
| + UNREACHABLE(); |
| + } |
|
siva
2015/08/19 19:40:02
indentation seems to be off.
|
| + } |
| } |
| @@ -1235,7 +1371,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(), |
| @@ -1256,7 +1393,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); |
| @@ -1275,7 +1412,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>(); |
| @@ -1300,7 +1438,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); |
| @@ -1321,7 +1459,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>(); |
| @@ -1351,7 +1490,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); |
| @@ -1373,7 +1512,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); |
| @@ -1399,7 +1539,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); |
| @@ -1487,15 +1627,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()); |
| } |
| @@ -1503,15 +1678,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()); |
| } |
| @@ -1519,15 +1729,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()); |
|
siva
2015/08/19 19:40:02
This is being read as a reference but the write si
rmacnak
2015/08/19 22:33:54
Switched write to reference.
|
| + |
| + 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_, kAsInlinedObject); |
| } |