| 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();
|
|
|