Index: runtime/vm/snapshot.cc |
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
index a57296f25d3d99d43f16abcf771f865ee65bad33..825cb6b802c6cfaf9dfa3854142ac35992fe7ccd 100644 |
--- a/runtime/vm/snapshot.cc |
+++ b/runtime/vm/snapshot.cc |
@@ -480,6 +480,8 @@ RawObject* SnapshotReader::ReadInstance(intptr_t object_id, |
AddBackRef(object_id, result, state); |
cls_ ^= ReadObjectImpl(kAsInlinedObject); |
ASSERT(!cls_.IsNull()); |
+ // Closure instances are handled by Closure::ReadFrom(). |
+ ASSERT(!cls_.IsClosureClass()); |
instance_size = cls_.instance_size(); |
ASSERT(instance_size > 0); |
// Allocate the instance and read in all the fields for the object. |
@@ -495,8 +497,7 @@ RawObject* SnapshotReader::ReadInstance(intptr_t object_id, |
} |
if (!as_reference) { |
// Read all the individual fields for inlined objects. |
- intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw()) |
- ? Closure::InstanceSize() : cls_.next_field_offset(); |
+ intptr_t next_field_offset = cls_.next_field_offset(); |
intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
ASSERT(next_field_offset > 0); |
@@ -921,6 +922,11 @@ RawType* SnapshotReader::NewType() { |
} |
+RawFunctionType* SnapshotReader::NewFunctionType() { |
+ ALLOC_NEW_OBJECT(FunctionType); |
+} |
+ |
+ |
RawTypeRef* SnapshotReader::NewTypeRef() { |
ALLOC_NEW_OBJECT(TypeRef); |
} |
@@ -946,6 +952,11 @@ RawPatchClass* SnapshotReader::NewPatchClass() { |
} |
+RawClosure* SnapshotReader::NewClosure() { |
+ ALLOC_NEW_OBJECT(Closure); |
+} |
+ |
+ |
RawClosureData* SnapshotReader::NewClosureData() { |
ALLOC_NEW_OBJECT(ClosureData); |
} |
@@ -1389,16 +1400,20 @@ void SnapshotReader::AddPatchRecord(intptr_t object_id, |
void SnapshotReader::ProcessDeferredCanonicalizations() { |
Type& typeobj = Type::Handle(); |
+ FunctionType& funtypeobj = FunctionType::Handle(); |
TypeArguments& typeargs = TypeArguments::Handle(); |
Object& newobj = Object::Handle(); |
for (intptr_t i = 0; i < backward_references_->length(); i++) { |
BackRefNode& backref = (*backward_references_)[i]; |
if (backref.defer_canonicalization()) { |
Object* objref = backref.reference(); |
- // Object should either be an abstract type or a type argument. |
+ // Object should either be a type, a function type, or a type argument. |
if (objref->IsType()) { |
typeobj ^= objref->raw(); |
newobj = typeobj.Canonicalize(); |
+ } else if (objref->IsFunctionType()) { |
+ funtypeobj ^= objref->raw(); |
+ newobj = funtypeobj.Canonicalize(); |
} else { |
ASSERT(objref->IsTypeArguments()); |
typeargs ^= objref->raw(); |
@@ -2321,33 +2336,28 @@ void SnapshotWriter::ArrayWriteTo(intptr_t object_id, |
} |
-RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, |
- RawObject* obj) { |
- if (Class::IsSignatureClass(cls)) { |
- // 'obj' is a closure as its class is a signature class, extract |
- // the function object to check if this closure can be sent in an |
- // isolate message. |
- RawFunction* func = Closure::GetFunction(obj); |
- // We only allow closure of top level methods or static functions in a |
- // class to be sent in isolate messages. |
- if (can_send_any_object() && |
- Function::IsImplicitStaticClosureFunction(func)) { |
- return func; |
- } |
- // Not a closure of a top level method or static function, throw an |
- // exception as we do not allow these objects to be serialized. |
- HANDLESCOPE(thread()); |
+RawFunction* SnapshotWriter::IsSerializableClosure(RawClosure* closure) { |
+ // Extract the function object to check if this closure |
+ // can be sent in an isolate message. |
+ RawFunction* func = closure->ptr()->function_; |
+ // We only allow closure of top level methods or static functions in a |
+ // class to be sent in isolate messages. |
+ if (can_send_any_object() && |
+ Function::IsImplicitStaticClosureFunction(func)) { |
+ return func; |
+ } |
+ // Not a closure of a top level method or static function, throw an |
+ // exception as we do not allow these objects to be serialized. |
+ HANDLESCOPE(thread()); |
- const Class& clazz = Class::Handle(zone(), cls); |
- const Function& errorFunc = Function::Handle(zone(), func); |
- ASSERT(!errorFunc.IsNull()); |
+ const Function& errorFunc = Function::Handle(zone(), func); |
+ ASSERT(!errorFunc.IsNull()); |
- // All other closures are errors. |
- char* chars = OS::SCreate(thread()->zone(), |
- "Illegal argument in isolate message : (object is a closure - %s %s)", |
- clazz.ToCString(), errorFunc.ToCString()); |
- SetWriteException(Exceptions::kArgument, chars); |
- } |
+ // All other closures are errors. |
+ char* chars = OS::SCreate(thread()->zone(), |
+ "Illegal argument in isolate message : (object is a closure - %s)", |
+ errorFunc.ToCString()); |
+ SetWriteException(Exceptions::kArgument, chars); |
return Function::null(); |
} |
@@ -2393,20 +2403,12 @@ void SnapshotWriter::WriteInstance(RawObject* raw, |
intptr_t tags, |
intptr_t object_id, |
bool as_reference) { |
+ // Closure instances are handled by RawClosure::WriteTo(). |
+ ASSERT(!Class::IsClosureClass(cls)); |
+ |
// Check if the instance has native fields and throw an exception if it does. |
CheckForNativeFields(cls); |
- if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) { |
- // Check if object is a closure that is serializable, if the object is a |
- // closure that is not serializable this will throw an exception. |
- RawFunction* func = IsSerializableClosure(cls, raw); |
- if (func != Function::null()) { |
- forward_list_->SetState(object_id, kIsSerialized); |
- WriteStaticImplicitClosure(object_id, func, tags); |
- return; |
- } |
- } |
- |
// Object is regular dart instance. |
if (as_reference) { |
// Write out the serialization header value for this object. |
@@ -2419,8 +2421,7 @@ void SnapshotWriter::WriteInstance(RawObject* raw, |
// Write out the class information for this object. |
WriteObjectImpl(cls, kAsInlinedObject); |
} else { |
- intptr_t next_field_offset = Class::IsSignatureClass(cls) ? |
- Closure::InstanceSize() : |
+ intptr_t next_field_offset = |
cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; |
ASSERT(next_field_offset > 0); |