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