Index: runtime/vm/snapshot.cc |
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
index 78fe6a70d2f910f8ec6c74c601e35cd268f996ad..ee4fb30dd67265062a6e4cb3db14fed35f8cbb45 100644 |
--- a/runtime/vm/snapshot.cc |
+++ b/runtime/vm/snapshot.cc |
@@ -455,15 +455,9 @@ CMessageReader::CMessageReader(const uint8_t* buffer, |
} |
-Dart_CMessage* CMessageReader::ReadMessage() { |
+Dart_CObject* CMessageReader::ReadMessage() { |
// Read the object out of the message. |
- Dart_CObject* object = ReadObject(); |
- |
- Dart_CMessage* message = |
- reinterpret_cast<Dart_CMessage*>(alloc_(NULL, 0, sizeof(Dart_CMessage))); |
- if (message == NULL) return NULL; |
- message->root = object; |
- return message; |
+ return ReadObject(); |
} |
intptr_t CMessageReader::LookupInternalClass(intptr_t class_header) { |
@@ -701,6 +695,136 @@ void MessageWriter::WriteMessage(intptr_t field_count, intptr_t *data) { |
} |
+void MessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) { |
+ // Mark the object as serialized by adding the object id to the |
+ // upper bits of the type field in the Dart_CObject structure. Add |
+ // an offset for making marking of object id 0 possible. |
+ ASSERT(!IsCObjectMarked(object)); |
+ intptr_t mark_value = object_id + kDartCObjectMarkOffset; |
+ object->type = static_cast<Dart_CObject::Type>( |
+ ((mark_value) << kDartCObjectTypeBits) | object->type); |
+} |
+ |
+ |
+void MessageWriter::UnmarkCObject(Dart_CObject* object) { |
+ ASSERT(IsCObjectMarked(object)); |
+ object->type = static_cast<Dart_CObject::Type>( |
+ object->type & kDartCObjectTypeMask); |
+} |
+ |
+ |
+bool MessageWriter::IsCObjectMarked(Dart_CObject* object) { |
+ return (object->type & kDartCObjectMarkMask) != 0; |
+} |
+ |
+ |
+intptr_t MessageWriter::GetMarkedCObjectMark(Dart_CObject* object) { |
+ ASSERT(IsCObjectMarked(object)); |
+ intptr_t mark_value = ((object->type & kDartCObjectMarkMask) >> 3); |
+ // An offset was added to object id for making marking object id 0 possible. |
+ return mark_value - kDartCObjectMarkOffset; |
+} |
+ |
+ |
+void MessageWriter::UnmarkAllCObjects(Dart_CObject* object) { |
+ if (!IsCObjectMarked(object)) return; |
+ UnmarkCObject(object); |
+ if (object->type == Dart_CObject::kArray) { |
+ for (int i = 0; i < object->value.as_array.length; i++) { |
+ Dart_CObject* element = object->value.as_array.values[i]; |
+ UnmarkAllCObjects(element); |
+ } |
+ } |
+} |
+ |
+ |
+void MessageWriter::WriteSmi(int32_t value) { |
+ Write<RawObject*>(Smi::New(value)); |
+} |
+ |
+ |
+void MessageWriter::WriteInlinedHeader(Dart_CObject* object) { |
+ // Write out the serialization header value for this object. |
+ WriteSerializationMarker(kInlined, kMaxPredefinedObjectIds + object_id_); |
+ // Mark object with its object id. |
+ MarkCObject(object, object_id_); |
+ // Advance object id. |
+ object_id_++; |
+} |
+ |
+ |
+void MessageWriter::WriteCObject(Dart_CObject* object) { |
+ if (IsCObjectMarked(object)) { |
+ intptr_t object_id = GetMarkedCObjectMark(object); |
+ WriteIndexedObject(kMaxPredefinedObjectIds + object_id); |
+ return; |
+ } |
+ |
+ switch (object->type) { |
+ case Dart_CObject::kNull: |
+ WriteIndexedObject(Object::kNullObject); |
+ break; |
+ case Dart_CObject::kBool: |
+ if (object->value.as_bool) { |
+ WriteIndexedObject(ObjectStore::kTrueValue); |
+ } else { |
+ WriteIndexedObject(ObjectStore::kFalseValue); |
+ } |
+ break; |
+ case Dart_CObject::kInt32: { |
+ WriteSmi(object->value.as_int32); |
+ break; |
+ } |
+ case Dart_CObject::kDouble: |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kDoubleClass, 0); |
+ // Write double value. |
+ Write<double>(object->value.as_double); |
+ break; |
+ case Dart_CObject::kString: { |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kOneByteStringClass, 0); |
+ // Write string length, hash and content |
+ char* str = object->value.as_string; |
+ intptr_t len = strlen(str); |
+ WriteSmi(len); |
+ WriteSmi(0); // TODO(sgjesse): Hash - not written. |
+ for (intptr_t i = 0; i < len; i++) { |
+ Write<uint8_t>(str[i]); |
+ } |
+ break; |
+ } |
+ case Dart_CObject::kArray: { |
+ // Write out the serialization header value for this object. |
+ WriteInlinedHeader(object); |
+ // Write out the class and tags information. |
+ WriteObjectHeader(ObjectStore::kArrayClass, 0); |
+ WriteSmi(object->value.as_array.length); |
+ // Write out the type arguments. |
+ WriteIndexedObject(Object::kNullObject); |
+ // Write out array elements. |
+ for (int i = 0; i < object->value.as_array.length; i++) { |
+ WriteCObject(object->value.as_array.values[i]); |
+ } |
+ break; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
+void MessageWriter::WriteCMessage(Dart_CObject* object) { |
+ WriteCObject(object); |
+ UnmarkAllCObjects(object); |
+ FinalizeBuffer(); |
+} |
+ |
+ |
void SnapshotWriter::WriteObject(RawObject* rawobj) { |
// An object is written in one of the following ways: |
// - Smi: the Smi value is written as is (last bit is not tagged). |