| 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).
 | 
| 
 |