Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(792)

Unified Diff: runtime/vm/snapshot.cc

Issue 1260033004: Fix for issue 23244 (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: indent-code Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/snapshot.h ('k') | tests/language/issue23244_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/snapshot.cc
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 391c9fc14e10c746c886084654300493d496eba4..f56780a5d197478753de3388ad742cc61a530ff3 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -206,10 +206,11 @@ RawObject* SnapshotReader::ReadObject() {
// Setup for long jump in case there is an exception while reading.
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
- PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl());
+ PassiveObject& obj =
+ PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject));
for (intptr_t i = 0; i < backward_references_->length(); i++) {
if (!(*backward_references_)[i].is_deserialized()) {
- ReadObjectImpl();
+ ReadObjectImpl(kAsInlinedObject);
(*backward_references_)[i].set_state(kIsDeserialized);
}
}
@@ -235,12 +236,12 @@ RawClass* SnapshotReader::ReadClassId(intptr_t object_id) {
Class& cls = Class::ZoneHandle(zone(), Class::null());
AddBackRef(object_id, &cls, kIsDeserialized);
// Read the library/class information and lookup the class.
- str_ ^= ReadObjectImpl(class_header);
+ str_ ^= ReadObjectImpl(class_header, kAsInlinedObject);
library_ = Library::LookupLibrary(str_);
if (library_.IsNull() || !library_.Loaded()) {
SetReadException("Invalid object found in message.");
}
- str_ ^= ReadObjectImpl();
+ str_ ^= ReadObjectImpl(kAsInlinedObject);
cls = library_.LookupClass(str_);
if (cls.IsNull()) {
SetReadException("Invalid object found in message.");
@@ -261,14 +262,14 @@ RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
AddBackRef(object_id, &obj, kIsDeserialized);
// Read the library/class/function information and lookup the function.
- str_ ^= ReadObjectImpl();
+ str_ ^= ReadObjectImpl(kAsInlinedObject);
library_ = Library::LookupLibrary(str_);
if (library_.IsNull() || !library_.Loaded()) {
SetReadException("Invalid Library object found in message.");
}
- str_ ^= ReadObjectImpl();
+ str_ ^= ReadObjectImpl(kAsInlinedObject);
if (str_.Equals(Symbols::TopLevel())) {
- str_ ^= ReadObjectImpl();
+ str_ ^= ReadObjectImpl(kAsInlinedObject);
func = library_.LookupFunctionAllowPrivate(str_);
} else {
cls_ = library_.LookupClassAllowPrivate(str_);
@@ -277,7 +278,7 @@ RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
SetReadException("Invalid Class object found in message.");
}
cls_.EnsureIsFinalized(isolate());
- str_ ^= ReadObjectImpl();
+ str_ ^= ReadObjectImpl(kAsInlinedObject);
func = cls_.LookupFunctionAllowPrivate(str_);
}
if (func.IsNull()) {
@@ -292,16 +293,6 @@ RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
}
-RawObject* SnapshotReader::ReadObjectImpl() {
- int64_t value = Read<int64_t>();
- if ((value & kSmiTagMask) == kSmiTag) {
- return NewInteger(value);
- }
- ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
- return ReadObjectImpl(static_cast<intptr_t>(value));
-}
-
-
intptr_t SnapshotReader::NextAvailableObjectId() const {
return backward_references_->length() +
kMaxPredefinedObjectIds + max_vm_isolate_object_id_;
@@ -331,7 +322,18 @@ RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
}
-RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) {
+RawObject* SnapshotReader::ReadObjectImpl(bool as_reference) {
+ int64_t header_value = Read<int64_t>();
+ if ((header_value & kSmiTagMask) == kSmiTag) {
+ return NewInteger(header_value);
+ }
+ ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin));
+ return ReadObjectImpl(static_cast<intptr_t>(header_value), as_reference);
+}
+
+
+RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value,
+ bool as_reference) {
if (IsVMIsolateObject(header_value)) {
return ReadVMIsolateObject(header_value);
} else {
@@ -343,33 +345,22 @@ RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) {
if (object_id == kOmittedObjectId) {
object_id = NextAvailableObjectId();
}
- return ReadInlinedObject(object_id);
- }
-}
-
-RawObject* SnapshotReader::ReadObjectRef() {
- int64_t header_value = Read<int64_t>();
- if ((header_value & kSmiTagMask) == kSmiTag) {
- return NewInteger(header_value);
- }
- ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin));
- intptr_t value = static_cast<intptr_t>(header_value);
- if (IsVMIsolateObject(value)) {
- return ReadVMIsolateObject(value);
- } else if (SerializedHeaderTag::decode(value) == kObjectId) {
- return ReadIndexedObject(SerializedHeaderData::decode(value));
- }
- ASSERT(SerializedHeaderTag::decode(value) == kInlined);
- intptr_t object_id = SerializedHeaderData::decode(value);
- if (object_id == kOmittedObjectId) {
- object_id = NextAvailableObjectId();
+ // Read the class header information.
+ intptr_t class_header = Read<int32_t>();
+ intptr_t tags = ReadTags();
+ if (as_reference && !RawObject::IsCanonical(tags)) {
+ return ReadObjectRef(object_id, class_header, tags);
+ } else {
+ return ReadInlinedObject(object_id, class_header, tags);
+ }
}
- ASSERT(GetBackRef(object_id) == NULL);
+}
- // Read the class header information and lookup the class.
- intptr_t class_header = Read<int32_t>();
+RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id,
+ intptr_t class_header,
+ intptr_t tags) {
// Since we are only reading an object reference, If it is an instance kind
// then we only need to figure out the class of the object and allocate an
// instance of it. The individual fields will be read later.
@@ -378,7 +369,7 @@ RawObject* SnapshotReader::ReadObjectRef() {
Instance& result = Instance::ZoneHandle(zone(), Instance::null());
AddBackRef(object_id, &result, kIsNotDeserialized);
- cls_ ^= ReadObjectImpl(); // Read class information.
+ cls_ ^= ReadObjectImpl(kAsInlinedObject); // Read class information.
ASSERT(!cls_.IsNull());
intptr_t instance_size = cls_.instance_size();
ASSERT(instance_size > 0);
@@ -392,7 +383,6 @@ RawObject* SnapshotReader::ReadObjectRef() {
// We skip the tags that have been written as the implicit static
// closure is going to be created in this isolate or the canonical
// version already created in the isolate will be used.
- ReadTags();
return ReadStaticImplicitClosure(object_id, class_header);
}
ASSERT((class_header & kSmiTagMask) != kSmiTag);
@@ -424,7 +414,119 @@ RawObject* SnapshotReader::ReadObjectRef() {
}
// For all other internal VM classes we read the object inline.
- intptr_t tags = ReadTags();
+ switch (class_id) {
+#define SNAPSHOT_READ(clazz) \
+ case clazz::kClassId: { \
+ pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \
+ break; \
+ }
+ CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
+#undef SNAPSHOT_READ
+#define SNAPSHOT_READ(clazz) \
+ case kTypedData##clazz##Cid: \
+
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
+ tags = RawObject::ClassIdTag::update(class_id, tags);
+ pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_);
+ break;
+ }
+#undef SNAPSHOT_READ
+#define SNAPSHOT_READ(clazz) \
+ case kExternalTypedData##clazz##Cid: \
+
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
+ tags = RawObject::ClassIdTag::update(class_id, tags);
+ pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_);
+ break;
+ }
+#undef SNAPSHOT_READ
+ default: UNREACHABLE(); break;
+ }
+ if (kind_ == Snapshot::kFull) {
+ pobj_.SetCreatedFromSnapshot();
+ }
+ return pobj_.raw();
+}
+
+
+RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id,
+ intptr_t class_header,
+ intptr_t tags) {
+ // Lookup the class based on the class header information.
+ intptr_t header_id = SerializedHeaderData::decode(class_header);
+ if (header_id == kInstanceObjectId) {
+ // Object is regular dart instance.
+ Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
+ intptr_t instance_size = 0;
+ if (result == NULL) {
+ result = &(Instance::ZoneHandle(zone(), Instance::null()));
+ AddBackRef(object_id, result, kIsDeserialized);
+ cls_ ^= ReadObjectImpl(kAsInlinedObject);
+ ASSERT(!cls_.IsNull());
+ instance_size = cls_.instance_size();
+ ASSERT(instance_size > 0);
+ // Allocate the instance and read in all the fields for the object.
+ if (kind_ == Snapshot::kFull) {
+ *result ^= AllocateUninitialized(cls_.id(), instance_size);
+ } else {
+ *result ^= Object::Allocate(cls_.id(),
+ instance_size,
+ HEAP_SPACE(kind_));
+ }
+ } else {
+ cls_ ^= ReadObjectImpl(kAsInlinedObject);
+ ASSERT(!cls_.IsNull());
+ instance_size = cls_.instance_size();
+ }
+ 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);
+ // Instance::NextFieldOffset() returns the offset of the first field in
+ // a Dart object.
+ bool as_reference = RawObject::IsCanonical(tags) ? false : true;
+ intptr_t offset = Instance::NextFieldOffset();
+ intptr_t result_cid = result->GetClassId();
+ while (offset < next_field_offset) {
+ pobj_ = ReadObjectImpl(as_reference);
+ result->SetFieldAtOffset(offset, pobj_);
+ if ((offset != type_argument_field_offset) &&
+ (kind_ == Snapshot::kMessage)) {
+ // TODO(fschneider): Consider hoisting these lookups out of the loop.
+ // This would involve creating a handle, since cls_ can't be reused
+ // across the call to ReadObjectRef.
+ cls_ = isolate()->class_table()->At(result_cid);
+ array_ = cls_.OffsetToFieldMap();
+ field_ ^= array_.At(offset >> kWordSizeLog2);
+ ASSERT(!field_.IsNull());
+ ASSERT(field_.Offset() == offset);
+ obj_ = pobj_.raw();
+ field_.RecordStore(obj_);
+ }
+ // TODO(fschneider): Verify the guarded cid and length for other kinds of
+ // snapshot (kFull, kScript) with asserts.
+ offset += kWordSize;
+ }
+ if (kind_ == Snapshot::kFull) {
+ // We create an uninitialized object in the case of full snapshots, so
+ // we need to initialize any remaining padding area with the Null object.
+ while (offset < instance_size) {
+ result->SetFieldAtOffset(offset, Object::null_object());
+ offset += kWordSize;
+ }
+ result->SetCreatedFromSnapshot();
+ } else if (RawObject::IsCanonical(tags)) {
+ *result = result->CheckAndCanonicalize(NULL);
+ ASSERT(!result->IsNull());
+ }
+ return result->raw();
+ } else if (header_id == kStaticImplicitClosureObjectId) {
+ // We do not use the tags as the implicit static closure
+ // is going to be created in this isolate or the canonical
+ // version already created in the isolate will be used.
+ return ReadStaticImplicitClosure(object_id, class_header);
+ }
+ ASSERT((class_header & kSmiTagMask) != kSmiTag);
+ intptr_t class_id = LookupInternalClass(class_header);
switch (class_id) {
#define SNAPSHOT_READ(clazz) \
case clazz::kClassId: { \
@@ -523,11 +625,11 @@ RawApiError* SnapshotReader::ReadFullSnapshot() {
// Read in all the objects stored in the object store.
intptr_t num_flds = (object_store->to() - object_store->from());
for (intptr_t i = 0; i <= num_flds; i++) {
- *(object_store->from() + i) = ReadObjectImpl();
+ *(object_store->from() + i) = ReadObjectImpl(kAsInlinedObject);
}
for (intptr_t i = 0; i < backward_references_->length(); i++) {
if (!(*backward_references_)[i].is_deserialized()) {
- ReadObjectImpl();
+ ReadObjectImpl(kAsInlinedObject);
(*backward_references_)[i].set_state(kIsDeserialized);
}
}
@@ -1011,119 +1113,6 @@ RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) {
}
-RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) {
- // Read the class header information and lookup the class.
- intptr_t class_header = Read<int32_t>();
- intptr_t tags = ReadTags();
- intptr_t header_id = SerializedHeaderData::decode(class_header);
- if (header_id == kInstanceObjectId) {
- // Object is regular dart instance.
- Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
- intptr_t instance_size = 0;
- if (result == NULL) {
- result = &(Instance::ZoneHandle(zone(), Instance::null()));
- AddBackRef(object_id, result, kIsDeserialized);
- cls_ ^= ReadObjectImpl();
- ASSERT(!cls_.IsNull());
- instance_size = cls_.instance_size();
- ASSERT(instance_size > 0);
- // Allocate the instance and read in all the fields for the object.
- if (kind_ == Snapshot::kFull) {
- *result ^= AllocateUninitialized(cls_.id(), instance_size);
- } else {
- *result ^= Object::Allocate(cls_.id(),
- instance_size,
- HEAP_SPACE(kind_));
- }
- } else {
- cls_ ^= ReadObjectImpl();
- ASSERT(!cls_.IsNull());
- instance_size = cls_.instance_size();
- }
- 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);
- // Instance::NextFieldOffset() returns the offset of the first field in
- // a Dart object.
- bool is_canonical = RawObject::IsCanonical(tags);
- intptr_t offset = Instance::NextFieldOffset();
- intptr_t result_cid = result->GetClassId();
- while (offset < next_field_offset) {
- pobj_ = is_canonical ? ReadObjectImpl() : ReadObjectRef();
- result->SetFieldAtOffset(offset, pobj_);
- if ((offset != type_argument_field_offset) &&
- (kind_ == Snapshot::kMessage)) {
- // TODO(fschneider): Consider hoisting these lookups out of the loop.
- // This would involve creating a handle, since cls_ can't be reused
- // across the call to ReadObjectRef.
- cls_ = isolate()->class_table()->At(result_cid);
- array_ = cls_.OffsetToFieldMap();
- field_ ^= array_.At(offset >> kWordSizeLog2);
- ASSERT(!field_.IsNull());
- ASSERT(field_.Offset() == offset);
- obj_ = pobj_.raw();
- field_.RecordStore(obj_);
- }
- // TODO(fschneider): Verify the guarded cid and length for other kinds of
- // snapshot (kFull, kScript) with asserts.
- offset += kWordSize;
- }
- if (kind_ == Snapshot::kFull) {
- // We create an uninitialized object in the case of full snapshots, so
- // we need to initialize any remaining padding area with the Null object.
- while (offset < instance_size) {
- result->SetFieldAtOffset(offset, Object::null_object());
- offset += kWordSize;
- }
- result->SetCreatedFromSnapshot();
- } else if (RawObject::IsCanonical(tags)) {
- *result = result->CheckAndCanonicalize(NULL);
- ASSERT(!result->IsNull());
- }
- return result->raw();
- } else if (header_id == kStaticImplicitClosureObjectId) {
- // We do not use the tags as the implicit static closure
- // is going to be created in this isolate or the canonical
- // version already created in the isolate will be used.
- return ReadStaticImplicitClosure(object_id, class_header);
- }
- ASSERT((class_header & kSmiTagMask) != kSmiTag);
- intptr_t class_id = LookupInternalClass(class_header);
- switch (class_id) {
-#define SNAPSHOT_READ(clazz) \
- case clazz::kClassId: { \
- pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \
- break; \
- }
- CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz) \
- case kTypedData##clazz##Cid: \
-
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = RawObject::ClassIdTag::update(class_id, tags);
- pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_);
- break;
- }
-#undef SNAPSHOT_READ
-#define SNAPSHOT_READ(clazz) \
- case kExternalTypedData##clazz##Cid: \
-
- CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
- tags = RawObject::ClassIdTag::update(class_id, tags);
- pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_);
- break;
- }
-#undef SNAPSHOT_READ
- default: UNREACHABLE(); break;
- }
- if (kind_ == Snapshot::kFull) {
- pobj_.SetCreatedFromSnapshot();
- }
- return pobj_.raw();
-}
-
-
void SnapshotReader::ArrayReadFrom(const Array& result,
intptr_t len,
intptr_t tags) {
@@ -1131,13 +1120,13 @@ void SnapshotReader::ArrayReadFrom(const Array& result,
result.set_tags(tags);
// Setup the object fields.
- *TypeArgumentsHandle() ^= ReadObjectImpl();
+ *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject);
result.SetTypeArguments(*TypeArgumentsHandle());
- bool is_canonical = RawObject::IsCanonical(tags);
+ bool as_reference = RawObject::IsCanonical(tags) ? false : true;
for (intptr_t i = 0; i < len; i++) {
- *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef();
+ *PassiveObjectHandle() = ReadObjectImpl(as_reference);
result.SetAt(i, *PassiveObjectHandle());
}
}
@@ -1284,7 +1273,7 @@ SnapshotWriter::SnapshotWriter(Snapshot::Kind kind,
void SnapshotWriter::WriteObject(RawObject* rawobj) {
- WriteObjectImpl(rawobj);
+ WriteObjectImpl(rawobj, kAsInlinedObject);
WriteForwardedObjects();
}
@@ -1407,104 +1396,6 @@ void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
#undef VM_OBJECT_WRITE
-void SnapshotWriter::WriteObjectRef(RawObject* raw) {
- // First check if object can be written as a simple predefined type.
- if (CheckAndWritePredefinedObject(raw)) {
- return;
- }
-
- NoSafepointScope no_safepoint;
- RawClass* cls = class_table_->At(raw->GetClassId());
- intptr_t class_id = cls->ptr()->id_;
- ASSERT(class_id == raw->GetClassId());
- if (class_id >= kNumPredefinedCids) {
- WriteInstanceRef(raw, cls);
- return;
- }
- if (class_id == kArrayCid) {
- // 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.
- forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
-
- RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
-
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(kOmittedObjectId);
-
- // Write out the class information.
- WriteIndexedObject(kArrayCid);
-
- // Write out the length field.
- Write<RawObject*>(rawarray->ptr()->length_);
-
- return;
- }
- if (class_id == kImmutableArrayCid) {
- // 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.
- forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
-
- RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
-
- // Write out the serialization header value for this object.
- WriteInlinedObjectHeader(kOmittedObjectId);
-
- // Write out the class information.
- WriteIndexedObject(kImmutableArrayCid);
-
- // Write out the length field.
- Write<RawObject*>(rawarray->ptr()->length_);
-
- return;
- }
- if (RawObject::IsImplicitFieldClassId(class_id)) {
- WriteInstanceRef(raw, cls);
- return;
- }
- // Add object 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 having
- // been serialized so that we do not serialize the object when we go through
- // the forward list.
- forward_list_->MarkAndAddObject(raw, kIsSerialized);
- switch (class_id) {
-#define SNAPSHOT_WRITE(clazz) \
- case clazz::kClassId: { \
- Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
- raw_obj->WriteTo(this, kOmittedObjectId, kind_); \
- return; \
- } \
-
- CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
-#undef SNAPSHOT_WRITE
-#define SNAPSHOT_WRITE(clazz) \
- case kTypedData##clazz##Cid: \
-
- CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
- RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
- raw_obj->WriteTo(this, kOmittedObjectId, 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, kOmittedObjectId, kind_);
- return;
- }
-#undef SNAPSHOT_WRITE
- default: break;
- }
- UNREACHABLE();
-}
-
-
// An object visitor which will iterate over all the script objects in the heap
// and either count them or collect them into an array. This is used during
// full snapshot generation of the VM isolate to write out all script
@@ -1853,18 +1744,95 @@ bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) {
}
-void SnapshotWriter::WriteObjectImpl(RawObject* raw) {
+void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) {
// First check if object can be written as a simple predefined type.
if (CheckAndWritePredefinedObject(raw)) {
return;
}
- // Object is being serialized, add it to the forward ref list and mark
- // it so that future references to this object in the snapshot will use
- // an object id, instead of trying to serialize it again.
+ if (as_reference && !raw->IsCanonical()) {
+ WriteObjectRef(raw);
+ } else {
+ // Object is being serialized, add it to the forward ref list and mark
+ // it so that future references to this object in the snapshot will use
+ // an object id, instead of trying to serialize it again.
+ forward_list_->MarkAndAddObject(raw, kIsSerialized);
+
+ WriteInlinedObject(raw);
+ }
+}
+
+
+void SnapshotWriter::WriteObjectRef(RawObject* raw) {
+ NoSafepointScope no_safepoint;
+ RawClass* cls = class_table_->At(raw->GetClassId());
+ intptr_t class_id = cls->ptr()->id_;
+ ASSERT(class_id == raw->GetClassId());
+ if (class_id >= kNumPredefinedCids ||
+ RawObject::IsImplicitFieldClassId(class_id)) {
+ WriteInstanceRef(raw, cls);
+ return;
+ }
+ if (class_id == kArrayCid || class_id == kImmutableArrayCid) {
+ intptr_t tags = GetObjectTags(raw);
+
+ // 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.
+ forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
+
+ RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
+
+ // Write out the serialization header value for this object.
+ WriteInlinedObjectHeader(kOmittedObjectId);
+
+ // Write out the class information.
+ WriteIndexedObject(class_id);
+ WriteTags(tags);
+
+ // Write out the length field.
+ Write<RawObject*>(rawarray->ptr()->length_);
+
+ return;
+ }
+ // Add object 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 having
+ // been serialized so that we do not serialize the object when we go through
+ // the forward list.
forward_list_->MarkAndAddObject(raw, kIsSerialized);
+ switch (class_id) {
+#define SNAPSHOT_WRITE(clazz) \
+ case clazz::kClassId: { \
+ Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
+ raw_obj->WriteTo(this, kOmittedObjectId, kind_); \
+ return; \
+ } \
- WriteInlinedObject(raw);
+ CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
+#undef SNAPSHOT_WRITE
+#define SNAPSHOT_WRITE(clazz) \
+ case kTypedData##clazz##Cid: \
+
+ CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
+ RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
+ raw_obj->WriteTo(this, kOmittedObjectId, 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, kOmittedObjectId, kind_);
+ return;
+ }
+#undef SNAPSHOT_WRITE
+ default: break;
+ }
+ UNREACHABLE();
}
@@ -1994,8 +1962,8 @@ void SnapshotWriter::WriteClassId(RawClass* cls) {
// Write out the library url and class name.
RawLibrary* library = cls->ptr()->library_;
ASSERT(library != Library::null());
- WriteObjectImpl(library->ptr()->url_);
- WriteObjectImpl(cls->ptr()->name_);
+ WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
+ WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
}
@@ -2016,9 +1984,9 @@ void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
ASSERT(cls != Class::null());
RawLibrary* library = cls->ptr()->library_;
ASSERT(library != Library::null());
- WriteObjectImpl(library->ptr()->url_);
- WriteObjectImpl(cls->ptr()->name_);
- WriteObjectImpl(func->ptr()->name_);
+ WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
+ WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
+ WriteObjectImpl(func->ptr()->name_, kAsInlinedObject);
}
@@ -2041,16 +2009,12 @@ void SnapshotWriter::ArrayWriteTo(intptr_t object_id,
Write<RawObject*>(length);
// Write out the type arguments.
- WriteObjectImpl(type_arguments);
+ WriteObjectImpl(type_arguments, kAsInlinedObject);
// Write out the individual object ids.
- bool is_canonical = RawObject::IsCanonical(tags);
+ bool as_reference = RawObject::IsCanonical(tags) ? false : true;
for (intptr_t i = 0; i < len; i++) {
- if (is_canonical) {
- WriteObjectImpl(data[i]);
- } else {
- WriteObjectRef(data[i]);
- }
+ WriteObjectImpl(data[i], as_reference);
}
}
@@ -2159,21 +2123,17 @@ void SnapshotWriter::WriteInstance(intptr_t object_id,
WriteTags(tags);
// Write out the class information for this object.
- WriteObjectImpl(cls);
+ WriteObjectImpl(cls, kAsInlinedObject);
// Write out all the fields for the object.
// Instance::NextFieldOffset() returns the offset of the first field in
// a Dart object.
- bool is_canonical = RawObject::IsCanonical(tags);
+ bool as_reference = RawObject::IsCanonical(tags) ? false : true;
intptr_t offset = Instance::NextFieldOffset();
while (offset < next_field_offset) {
RawObject* raw_obj = *reinterpret_cast<RawObject**>(
reinterpret_cast<uword>(raw->ptr()) + offset);
- if (is_canonical) {
- WriteObjectImpl(raw_obj);
- } else {
- WriteObjectRef(raw_obj);
- }
+ WriteObjectImpl(raw_obj, as_reference);
offset += kWordSize;
}
return;
@@ -2205,6 +2165,7 @@ void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) {
// 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 tags = raw->ptr()->tags_;
forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
// Write out the serialization header value for this object.
@@ -2212,9 +2173,10 @@ void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) {
// Indicate this is an instance object.
Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId));
+ WriteTags(tags);
// Write out the class information for this object.
- WriteObjectImpl(cls);
+ WriteObjectImpl(cls, kAsInlinedObject);
}
@@ -2313,11 +2275,7 @@ void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) {
void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) {
for (RawObject** current = first; current <= last; current++) {
RawObject* raw_obj = *current;
- if (as_references_) {
- writer_->WriteObjectRef(raw_obj);
- } else {
- writer_->WriteObjectImpl(raw_obj);
- }
+ writer_->WriteObjectImpl(raw_obj, as_references_);
}
}
« no previous file with comments | « runtime/vm/snapshot.h ('k') | tests/language/issue23244_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698