| Index: runtime/vm/raw_object_snapshot.cc
|
| diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
|
| index 223a93139bf373e984ea1d6ddd55c733f5b65c83..4b92cccc9b6fbcab11553f8570ccdce3ec6475ce 100644
|
| --- a/runtime/vm/raw_object_snapshot.cc
|
| +++ b/runtime/vm/raw_object_snapshot.cc
|
| @@ -237,7 +237,7 @@ RawType* Type::ReadFrom(SnapshotReader* reader,
|
| READ_OBJECT_FIELDS(type, type.raw()->from(), type.raw()->to(), kAsReference);
|
|
|
| // Set the canonical bit.
|
| - if (!defer_canonicalization && RawObject::IsCanonical(tags)) {
|
| + if (!defer_canonicalization && is_canonical) {
|
| type.SetCanonical();
|
| }
|
|
|
| @@ -275,15 +275,89 @@ void RawType::WriteTo(SnapshotWriter* writer,
|
| writer->Write<int32_t>(ptr()->token_pos_);
|
| writer->Write<int8_t>(ptr()->type_state_);
|
|
|
| - // Write out all the object pointer fields. Since we will be canonicalizing
|
| - // the type object when reading it back we should write out all the fields
|
| - // inline and not as references.
|
| + // Write out all the object pointer fields.
|
| ASSERT(ptr()->type_class_ != Object::null());
|
| SnapshotWriterVisitor visitor(writer, kAsReference);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
|
|
| +RawFunctionType* FunctionType::ReadFrom(SnapshotReader* reader,
|
| + intptr_t object_id,
|
| + intptr_t tags,
|
| + Snapshot::Kind kind,
|
| + bool as_reference) {
|
| + ASSERT(reader != NULL);
|
| +
|
| + // Determine if the scope class of this function type is in the full snapshot.
|
| + bool scopeclass_is_in_fullsnapshot = reader->Read<bool>();
|
| +
|
| + // Allocate function type object.
|
| + FunctionType& function_type =
|
| + FunctionType::ZoneHandle(reader->zone(), NEW_OBJECT(FunctionType));
|
| + bool is_canonical = RawObject::IsCanonical(tags);
|
| + bool defer_canonicalization = is_canonical &&
|
| + (kind != Snapshot::kFull && scopeclass_is_in_fullsnapshot);
|
| + reader->AddBackRef(object_id,
|
| + &function_type,
|
| + kIsDeserialized,
|
| + defer_canonicalization);
|
| +
|
| + // Set all non object fields.
|
| + function_type.set_token_pos(reader->Read<int32_t>());
|
| + function_type.set_type_state(reader->Read<int8_t>());
|
| +
|
| + // Set all the object fields.
|
| + READ_OBJECT_FIELDS(function_type,
|
| + function_type.raw()->from(), function_type.raw()->to(),
|
| + kAsReference);
|
| +
|
| + // Set the canonical bit.
|
| + if (!defer_canonicalization && is_canonical) {
|
| + function_type.SetCanonical();
|
| + }
|
| +
|
| + return function_type.raw();
|
| +}
|
| +
|
| +
|
| +void RawFunctionType::WriteTo(SnapshotWriter* writer,
|
| + intptr_t object_id,
|
| + Snapshot::Kind kind,
|
| + bool as_reference) {
|
| + ASSERT(writer != NULL);
|
| +
|
| + // Only resolved and finalized function types should be written to a snapshot.
|
| + ASSERT((ptr()->type_state_ == RawFunctionType::kFinalizedInstantiated) ||
|
| + (ptr()->type_state_ == RawFunctionType::kFinalizedUninstantiated));
|
| + ASSERT(ptr()->scope_class_ != Object::null());
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteIndexedObject(kFunctionTypeCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out scopeclass_is_in_fullsnapshot first as this will
|
| + // help the reader decide on how to canonicalize the type object.
|
| + intptr_t tags = writer->GetObjectTags(ptr()->scope_class_);
|
| + bool scopeclass_is_in_fullsnapshot =
|
| + (ClassIdTag::decode(tags) == kClassCid) &&
|
| + Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(ptr()->scope_class_));
|
| + writer->Write<bool>(scopeclass_is_in_fullsnapshot);
|
| +
|
| + // Write out all the non object pointer fields.
|
| + writer->Write<int32_t>(ptr()->token_pos_);
|
| + writer->Write<int8_t>(ptr()->type_state_);
|
| +
|
| + // Write out all the object pointer fields.
|
| + ASSERT(ptr()->scope_class_ != Object::null());
|
| + SnapshotWriterVisitor visitor(writer, kAsReference);
|
| + visitor.VisitPointers(from(), to());
|
| +}
|
| +
|
| +
|
| RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| @@ -472,7 +546,7 @@ RawTypeArguments* TypeArguments::ReadFrom(SnapshotReader* reader,
|
| }
|
|
|
| // Set the canonical bit.
|
| - if (!defer_canonicalization && RawObject::IsCanonical(tags)) {
|
| + if (!defer_canonicalization && is_canonical) {
|
| type_arguments.SetCanonical();
|
| }
|
|
|
| @@ -548,6 +622,57 @@ void RawPatchClass::WriteTo(SnapshotWriter* writer,
|
| }
|
|
|
|
|
| +RawClosure* Closure::ReadFrom(SnapshotReader* reader,
|
| + intptr_t object_id,
|
| + intptr_t tags,
|
| + Snapshot::Kind kind,
|
| + bool as_reference) {
|
| + ASSERT(reader != NULL);
|
| + ASSERT(kind == Snapshot::kFull);
|
| +
|
| + // Allocate closure object.
|
| + Closure& closure = Closure::ZoneHandle(
|
| + reader->zone(), NEW_OBJECT(Closure));
|
| + reader->AddBackRef(object_id, &closure, kIsDeserialized);
|
| +
|
| + // Set all the object fields.
|
| + READ_OBJECT_FIELDS(closure,
|
| + closure.raw()->from(), closure.raw()->to(),
|
| + kAsReference);
|
| +
|
| + return closure.raw();
|
| +}
|
| +
|
| +
|
| +void RawClosure::WriteTo(SnapshotWriter* writer,
|
| + intptr_t object_id,
|
| + Snapshot::Kind kind,
|
| + bool as_reference) {
|
| + ASSERT(writer != NULL);
|
| + if ((kind == Snapshot::kMessage) || (kind == Snapshot::kScript)) {
|
| + // Check if closure is serializable, throw an exception otherwise.
|
| + RawFunction* func = writer->IsSerializableClosure(this);
|
| + if (func != Function::null()) {
|
| + writer->WriteStaticImplicitClosure(object_id,
|
| + func,
|
| + writer->GetObjectTags(this));
|
| + return;
|
| + }
|
| + }
|
| +
|
| + // Write out the serialization header value for this object.
|
| + writer->WriteInlinedObjectHeader(object_id);
|
| +
|
| + // Write out the class and tags information.
|
| + writer->WriteIndexedObject(kClosureCid);
|
| + writer->WriteTags(writer->GetObjectTags(this));
|
| +
|
| + // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer, kAsReference);
|
| + visitor.VisitPointers(from(), to());
|
| +}
|
| +
|
| +
|
| RawClosureData* ClosureData::ReadFrom(SnapshotReader* reader,
|
| intptr_t object_id,
|
| intptr_t tags,
|
| @@ -599,8 +724,8 @@ void RawClosureData::WriteTo(SnapshotWriter* writer,
|
| // Parent function.
|
| writer->WriteObjectImpl(ptr()->parent_function_, kAsInlinedObject);
|
|
|
| - // Signature class.
|
| - writer->WriteObjectImpl(ptr()->signature_class_, kAsInlinedObject);
|
| + // Signature type.
|
| + writer->WriteObjectImpl(ptr()->signature_type_, kAsInlinedObject);
|
|
|
| // Static closure/Closure allocation stub.
|
| // We don't write the closure or allocation stub in the snapshot.
|
| @@ -723,7 +848,7 @@ void RawFunction::WriteTo(SnapshotWriter* writer,
|
| ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
| bool is_in_fullsnapshot = false;
|
| bool owner_is_class = false;
|
| - if (kind == Snapshot::kScript) {
|
| + if ((kind == Snapshot::kScript) && !Function::IsSignatureFunction(this)) {
|
| intptr_t tags = writer->GetObjectTags(ptr()->owner_);
|
| intptr_t cid = ClassIdTag::decode(tags);
|
| owner_is_class = (cid == kClassCid);
|
|
|