Index: runtime/vm/snapshot.cc |
=================================================================== |
--- runtime/vm/snapshot.cc (revision 20452) |
+++ runtime/vm/snapshot.cc (working copy) |
@@ -54,6 +54,7 @@ |
static intptr_t ObjectIdFromClassId(intptr_t class_id) { |
ASSERT((class_id > kIllegalCid) && (class_id < kNumPredefinedCids)); |
+ ASSERT(!RawObject::IsTypedDataViewClassId(class_id)); |
return (class_id + kClassIdsOffset); |
} |
@@ -315,16 +316,21 @@ |
CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
#undef SNAPSHOT_READ |
#define SNAPSHOT_READ(clazz) \ |
- case kTypedData##clazz##Cid: { \ |
- obj_ = TypedData::ReadFrom(this, object_id, tags, kind_); \ |
- break; \ |
- } \ |
- case kExternalTypedData##clazz##Cid: { \ |
- obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); \ |
- break; \ |
+ case kTypedData##clazz##Cid: \ |
+ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
+ obj_ = TypedData::ReadFrom(this, object_id, tags, kind_); |
+ break; |
} |
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) |
#undef SNAPSHOT_READ |
+#define SNAPSHOT_READ(clazz) \ |
+ case kExternalTypedData##clazz##Cid: \ |
+ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
+ obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
+ break; |
+ } |
+#undef SNAPSHOT_READ |
default: UNREACHABLE(); break; |
} |
if (kind_ == Snapshot::kFull) { |
@@ -803,16 +809,21 @@ |
CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
#undef SNAPSHOT_READ |
#define SNAPSHOT_READ(clazz) \ |
- case kTypedData##clazz##Cid: { \ |
- obj_ = TypedData::ReadFrom(this, object_id, tags, kind_); \ |
- break; \ |
- } \ |
- case kExternalTypedData##clazz##Cid: { \ |
- obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); \ |
- break; \ |
+ case kTypedData##clazz##Cid: \ |
+ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
+ obj_ = TypedData::ReadFrom(this, object_id, tags, kind_); |
+ break; |
} |
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) |
#undef SNAPSHOT_READ |
+#define SNAPSHOT_READ(clazz) \ |
+ case kExternalTypedData##clazz##Cid: \ |
+ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
+ obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
+ break; |
+ } |
+#undef SNAPSHOT_READ |
default: UNREACHABLE(); break; |
} |
if (kind_ == Snapshot::kFull) { |
@@ -926,29 +937,7 @@ |
intptr_t class_id = cls->ptr()->id_; |
ASSERT(class_id == raw->GetClassId()); |
if (class_id >= kNumPredefinedCids) { |
- if (Class::IsSignatureClass(cls)) { |
- // We do not allow closure objects in an isolate message. |
- set_exception_type(Exceptions::kArgument); |
- // TODO(6726): Allocate these constant strings once in the VM isolate. |
- set_exception_msg("Illegal argument in isolate message" |
- " : (object is a closure)"); |
- Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
- } |
- // Object is being referenced, add it to the forward ref list and mark |
- // it so that future references to this object in the snapshot will use |
- // this object id. Mark it as not having been serialized yet so that we |
- // will serialize the object when we go through the forward list. |
- intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
- |
- // Write out the serialization header value for this object. |
- WriteInlinedObjectHeader(object_id); |
- |
- // Indicate this is an instance object. |
- WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
- |
- // Write out the class information for this object. |
- WriteObjectImpl(cls); |
- |
+ WriteInstanceRef(raw, cls); |
return; |
} |
if (class_id == kArrayCid) { |
@@ -1007,19 +996,32 @@ |
CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
#undef SNAPSHOT_WRITE |
#define SNAPSHOT_WRITE(clazz) \ |
- case kTypedData##clazz##Cid: { \ |
- RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); \ |
- raw_obj->WriteTo(this, object_id, kind_); \ |
- return; \ |
- } \ |
- case kExternalTypedData##clazz##Cid: { \ |
- RawExternalTypedData* raw_obj = \ |
- reinterpret_cast<RawExternalTypedData*>(raw); \ |
- raw_obj->WriteTo(this, object_id, kind_); \ |
- return; \ |
- } \ |
+ case kTypedData##clazz##Cid: \ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
+ RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); |
+ raw_obj->WriteTo(this, object_id, kind_); |
+ return; |
+ } |
+#undef SNAPSHOT_WRITE |
+#define SNAPSHOT_WRITE(clazz) \ |
+ case kExternalTypedData##clazz##Cid: \ |
+ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
+ RawExternalTypedData* raw_obj = |
+ reinterpret_cast<RawExternalTypedData*>(raw); |
+ raw_obj->WriteTo(this, object_id, kind_); |
+ return; |
+ } |
+#undef SNAPSHOT_WRITE |
+#define SNAPSHOT_WRITE(clazz) \ |
+ case kTypedData##clazz##ViewCid: \ |
+ |
CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) |
+ case kByteDataViewCid: { |
+ WriteInstanceRef(raw, cls); |
+ return; |
+ } |
#undef SNAPSHOT_WRITE |
default: break; |
} |
@@ -1198,47 +1200,7 @@ |
intptr_t class_id = cls->ptr()->id_; |
if (class_id >= kNumPredefinedCids) { |
- if (Class::IsSignatureClass(cls)) { |
- // We do not allow closure objects in an isolate message. |
- set_exception_type(Exceptions::kArgument); |
- // TODO(6726): Allocate these constant strings once in the VM isolate. |
- set_exception_msg("Illegal argument in isolate message" |
- " : (object is a closure)"); |
- Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
- } |
- if (cls->ptr()->num_native_fields_ != 0) { |
- // We do not allow objects with native fields in an isolate message. |
- set_exception_type(Exceptions::kArgument); |
- // TODO(6726): Allocate these constant strings once in the VM isolate. |
- set_exception_msg("Illegal argument in isolate message" |
- " : (object extends NativeWrapper)"); |
- |
- Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
- } |
- // Object is regular dart instance. |
- intptr_t instance_size = |
- cls->ptr()->instance_size_in_words_ << kWordSizeLog2; |
- ASSERT(instance_size != 0); |
- |
- // Write out the serialization header value for this object. |
- WriteInlinedObjectHeader(object_id); |
- |
- // Indicate this is an instance object. |
- WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
- |
- // Write out the tags. |
- WriteIntptrValue(tags); |
- |
- // Write out the class information for this object. |
- WriteObjectImpl(cls); |
- |
- // Write out all the fields for the object. |
- intptr_t offset = Object::InstanceSize(); |
- while (offset < instance_size) { |
- WriteObjectRef(*reinterpret_cast<RawObject**>( |
- reinterpret_cast<uword>(raw->ptr()) + offset)); |
- offset += kWordSize; |
- } |
+ WriteInstance(object_id, raw, cls, tags); |
return; |
} |
switch (class_id) { |
@@ -1252,19 +1214,32 @@ |
CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
#undef SNAPSHOT_WRITE |
#define SNAPSHOT_WRITE(clazz) \ |
- case kTypedData##clazz##Cid: { \ |
- RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); \ |
- raw_obj->WriteTo(this, object_id, kind_); \ |
- return; \ |
- } \ |
- case kExternalTypedData##clazz##Cid: { \ |
- RawExternalTypedData* raw_obj = \ |
- reinterpret_cast<RawExternalTypedData*>(raw); \ |
- raw_obj->WriteTo(this, object_id, kind_); \ |
- return; \ |
- } \ |
+ case kTypedData##clazz##Cid: \ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
+ RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); |
+ raw_obj->WriteTo(this, object_id, kind_); |
+ return; |
+ } |
+#undef SNAPSHOT_WRITE |
+#define SNAPSHOT_WRITE(clazz) \ |
+ case kExternalTypedData##clazz##Cid: \ |
+ |
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
+ RawExternalTypedData* raw_obj = |
+ reinterpret_cast<RawExternalTypedData*>(raw); |
+ raw_obj->WriteTo(this, object_id, kind_); |
+ return; |
+ } |
+#undef SNAPSHOT_WRITE |
+#define SNAPSHOT_WRITE(clazz) \ |
+ case kTypedData##clazz##ViewCid: \ |
+ |
CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) |
+ case kByteDataViewCid: { |
+ WriteInstance(object_id, raw, cls, tags); |
+ return; |
+ } |
#undef SNAPSHOT_WRITE |
default: break; |
} |
@@ -1344,6 +1319,83 @@ |
} |
+void SnapshotWriter::CheckIfSerializable(RawClass* cls) { |
+ if (Class::IsSignatureClass(cls)) { |
+ // We do not allow closure objects in an isolate message. |
+ set_exception_type(Exceptions::kArgument); |
+ // TODO(6726): Allocate these constant strings once in the VM isolate. |
+ set_exception_msg("Illegal argument in isolate message" |
+ " : (object is a closure)"); |
+ Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
+ } |
+ if (cls->ptr()->num_native_fields_ != 0) { |
+ // We do not allow objects with native fields in an isolate message. |
+ set_exception_type(Exceptions::kArgument); |
+ // TODO(6726): Allocate these constant strings once in the VM isolate. |
+ set_exception_msg("Illegal argument in isolate message" |
+ " : (object extends NativeWrapper)"); |
+ |
+ Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
+ } |
+} |
+ |
+ |
+void SnapshotWriter::WriteInstance(intptr_t object_id, |
+ RawObject* raw, |
+ RawClass* cls, |
+ intptr_t tags) { |
+ // First check if object is a closure or has native fields. |
+ CheckIfSerializable(cls); |
+ |
+ // Object is regular dart instance. |
+ intptr_t instance_size = |
+ cls->ptr()->instance_size_in_words_ << kWordSizeLog2; |
+ ASSERT(instance_size != 0); |
+ |
+ // Write out the serialization header value for this object. |
+ WriteInlinedObjectHeader(object_id); |
+ |
+ // Indicate this is an instance object. |
+ WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
+ |
+ // Write out the tags. |
+ WriteIntptrValue(tags); |
+ |
+ // Write out the class information for this object. |
+ WriteObjectImpl(cls); |
+ |
+ // Write out all the fields for the object. |
+ intptr_t offset = Object::InstanceSize(); |
+ while (offset < instance_size) { |
+ WriteObjectRef(*reinterpret_cast<RawObject**>( |
+ reinterpret_cast<uword>(raw->ptr()) + offset)); |
+ offset += kWordSize; |
+ } |
+ return; |
+} |
+ |
+ |
+void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
+ // First check if object is a closure or has native fields. |
+ CheckIfSerializable(cls); |
+ |
+ // Object is being referenced, add it to the forward ref list and mark |
+ // it so that future references to this object in the snapshot will use |
+ // this object id. Mark it as not having been serialized yet so that we |
+ // will serialize the object when we go through the forward list. |
+ intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
+ |
+ // Write out the serialization header value for this object. |
+ WriteInlinedObjectHeader(object_id); |
+ |
+ // Indicate this is an instance object. |
+ WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
+ |
+ // Write out the class information for this object. |
+ WriteObjectImpl(cls); |
+} |
+ |
+ |
void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, |
const char* msg) { |
Isolate::Current()->object_store()->clear_sticky_error(); |