| Index: runtime/vm/snapshot.cc
 | 
| ===================================================================
 | 
| --- runtime/vm/snapshot.cc	(revision 38172)
 | 
| +++ runtime/vm/snapshot.cc	(working copy)
 | 
| @@ -47,6 +47,17 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +static bool IsSplitClassId(intptr_t class_id) {
 | 
| +  // Return whether this class is serialized in two steps: first a reference,
 | 
| +  // with sufficient information to allocate a correctly sized object, and then
 | 
| +  // later inline with complete contents.
 | 
| +  return class_id >= kNumPredefinedCids ||
 | 
| +         class_id == kArrayCid ||
 | 
| +         class_id == kImmutableArrayCid ||
 | 
| +         RawObject::IsTypedDataViewClassId(class_id);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  static intptr_t ClassIdFromObjectId(intptr_t object_id) {
 | 
|    ASSERT(object_id > kClassIdsOffset);
 | 
|    intptr_t class_id = (object_id - kClassIdsOffset);
 | 
| @@ -221,6 +232,11 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +intptr_t SnapshotReader::NextAvailableObjectId() const {
 | 
| +  return backward_references_.length() + kMaxPredefinedObjectIds;
 | 
| +}
 | 
| +
 | 
| +
 | 
|  RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) {
 | 
|    ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin));
 | 
|    if (IsVMIsolateObject(header_value)) {
 | 
| @@ -230,7 +246,11 @@
 | 
|        return ReadIndexedObject(SerializedHeaderData::decode(header_value));
 | 
|      }
 | 
|      ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
 | 
| -    return ReadInlinedObject(SerializedHeaderData::decode(header_value));
 | 
| +    intptr_t object_id = SerializedHeaderData::decode(header_value);
 | 
| +    if (object_id == kOmittedObjectId) {
 | 
| +      object_id = NextAvailableObjectId();
 | 
| +    }
 | 
| +    return ReadInlinedObject(object_id);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -248,6 +268,9 @@
 | 
|    }
 | 
|    ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
 | 
|    intptr_t object_id = SerializedHeaderData::decode(header_value);
 | 
| +  if (object_id == kOmittedObjectId) {
 | 
| +    object_id = NextAvailableObjectId();
 | 
| +  }
 | 
|    ASSERT(GetBackRef(object_id) == NULL);
 | 
|  
 | 
|    // Read the class header information and lookup the class.
 | 
| @@ -1047,12 +1070,12 @@
 | 
|      // 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 = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
 | 
| +    forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
 | 
|  
 | 
|      RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
 | 
|  
 | 
|      // Write out the serialization header value for this object.
 | 
| -    WriteInlinedObjectHeader(object_id);
 | 
| +    WriteInlinedObjectHeader(kOmittedObjectId);
 | 
|  
 | 
|      // Write out the class information.
 | 
|      WriteIndexedObject(kArrayCid);
 | 
| @@ -1067,12 +1090,12 @@
 | 
|      // 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 = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
 | 
| +    forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
 | 
|  
 | 
|      RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
 | 
|  
 | 
|      // Write out the serialization header value for this object.
 | 
| -    WriteInlinedObjectHeader(object_id);
 | 
| +    WriteInlinedObjectHeader(kOmittedObjectId);
 | 
|  
 | 
|      // Write out the class information.
 | 
|      WriteIndexedObject(kImmutableArrayCid);
 | 
| @@ -1090,12 +1113,12 @@
 | 
|    // 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 = forward_list_.MarkAndAddObject(raw, kIsSerialized);
 | 
| +  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, object_id, kind_);                                \
 | 
| +      raw_obj->WriteTo(this, kOmittedObjectId, kind_);                         \
 | 
|        return;                                                                  \
 | 
|      }                                                                          \
 | 
|  
 | 
| @@ -1106,7 +1129,7 @@
 | 
|  
 | 
|      CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
 | 
|        RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
 | 
| -      raw_obj->WriteTo(this, object_id, kind_);
 | 
| +      raw_obj->WriteTo(this, kOmittedObjectId, kind_);
 | 
|        return;
 | 
|      }
 | 
|  #undef SNAPSHOT_WRITE
 | 
| @@ -1116,7 +1139,7 @@
 | 
|      CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
 | 
|        RawExternalTypedData* raw_obj =
 | 
|          reinterpret_cast<RawExternalTypedData*>(raw);
 | 
| -      raw_obj->WriteTo(this, object_id, kind_);
 | 
| +      raw_obj->WriteTo(this, kOmittedObjectId, kind_);
 | 
|        return;
 | 
|      }
 | 
|  #undef SNAPSHOT_WRITE
 | 
| @@ -1318,6 +1341,10 @@
 | 
|    RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
 | 
|    intptr_t class_id = cls->ptr()->id_;
 | 
|  
 | 
| +  if (!IsSplitClassId(class_id)) {
 | 
| +    object_id = kOmittedObjectId;
 | 
| +  }
 | 
| +
 | 
|    if (class_id >= kNumPredefinedCids) {
 | 
|      WriteInstance(object_id, raw, cls, tags);
 | 
|      return;
 | 
| @@ -1530,10 +1557,10 @@
 | 
|    // 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 = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
 | 
| +  forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
 | 
|  
 | 
|    // Write out the serialization header value for this object.
 | 
| -  WriteInlinedObjectHeader(object_id);
 | 
| +  WriteInlinedObjectHeader(kOmittedObjectId);
 | 
|  
 | 
|    // Indicate this is an instance object.
 | 
|    WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId));
 | 
| 
 |