OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/snapshot.h" | 5 #include "vm/snapshot.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 class_id == kNullCid); | 40 class_id == kNullCid); |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 static bool IsObjectStoreTypeId(intptr_t index) { | 44 static bool IsObjectStoreTypeId(intptr_t index) { |
45 // Check if this is a type which is stored in the object store. | 45 // Check if this is a type which is stored in the object store. |
46 return (index >= kObjectType && index <= kArrayType); | 46 return (index >= kObjectType && index <= kArrayType); |
47 } | 47 } |
48 | 48 |
49 | 49 |
| 50 static bool IsSplitClassId(intptr_t class_id) { |
| 51 // Return whether this class is serialized in two steps: first a reference, |
| 52 // with sufficient information to allocate a correctly sized object, and then |
| 53 // later inline with complete contents. |
| 54 return class_id >= kNumPredefinedCids || |
| 55 class_id == kArrayCid || |
| 56 class_id == kImmutableArrayCid || |
| 57 RawObject::IsTypedDataViewClassId(class_id); |
| 58 } |
| 59 |
| 60 |
50 static intptr_t ClassIdFromObjectId(intptr_t object_id) { | 61 static intptr_t ClassIdFromObjectId(intptr_t object_id) { |
51 ASSERT(object_id > kClassIdsOffset); | 62 ASSERT(object_id > kClassIdsOffset); |
52 intptr_t class_id = (object_id - kClassIdsOffset); | 63 intptr_t class_id = (object_id - kClassIdsOffset); |
53 return class_id; | 64 return class_id; |
54 } | 65 } |
55 | 66 |
56 | 67 |
57 static intptr_t ObjectIdFromClassId(intptr_t class_id) { | 68 static intptr_t ObjectIdFromClassId(intptr_t class_id) { |
58 ASSERT((class_id > kIllegalCid) && (class_id < kNumPredefinedCids)); | 69 ASSERT((class_id > kIllegalCid) && (class_id < kNumPredefinedCids)); |
59 ASSERT(!RawObject::IsTypedDataViewClassId(class_id)); | 70 ASSERT(!RawObject::IsTypedDataViewClassId(class_id)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 225 |
215 RawObject* SnapshotReader::ReadObjectImpl() { | 226 RawObject* SnapshotReader::ReadObjectImpl() { |
216 int64_t value = Read<int64_t>(); | 227 int64_t value = Read<int64_t>(); |
217 if ((value & kSmiTagMask) == kSmiTag) { | 228 if ((value & kSmiTagMask) == kSmiTag) { |
218 return NewInteger(value); | 229 return NewInteger(value); |
219 } | 230 } |
220 return ReadObjectImpl(value); | 231 return ReadObjectImpl(value); |
221 } | 232 } |
222 | 233 |
223 | 234 |
| 235 intptr_t SnapshotReader::NextAvailableObjectId() const { |
| 236 return backward_references_.length() + kMaxPredefinedObjectIds; |
| 237 } |
| 238 |
| 239 |
224 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { | 240 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { |
225 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | 241 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
226 if (IsVMIsolateObject(header_value)) { | 242 if (IsVMIsolateObject(header_value)) { |
227 return ReadVMIsolateObject(header_value); | 243 return ReadVMIsolateObject(header_value); |
228 } else { | 244 } else { |
229 if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 245 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
230 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 246 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
231 } | 247 } |
232 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 248 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
233 return ReadInlinedObject(SerializedHeaderData::decode(header_value)); | 249 intptr_t object_id = SerializedHeaderData::decode(header_value); |
| 250 if (object_id == kOmittedObjectId) { |
| 251 object_id = NextAvailableObjectId(); |
| 252 } |
| 253 return ReadInlinedObject(object_id); |
234 } | 254 } |
235 } | 255 } |
236 | 256 |
237 | 257 |
238 RawObject* SnapshotReader::ReadObjectRef() { | 258 RawObject* SnapshotReader::ReadObjectRef() { |
239 int64_t header_value = Read<int64_t>(); | 259 int64_t header_value = Read<int64_t>(); |
240 if ((header_value & kSmiTagMask) == kSmiTag) { | 260 if ((header_value & kSmiTagMask) == kSmiTag) { |
241 return NewInteger(header_value); | 261 return NewInteger(header_value); |
242 } | 262 } |
243 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | 263 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
244 if (IsVMIsolateObject(header_value)) { | 264 if (IsVMIsolateObject(header_value)) { |
245 return ReadVMIsolateObject(header_value); | 265 return ReadVMIsolateObject(header_value); |
246 } else if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 266 } else if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
247 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 267 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
248 } | 268 } |
249 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 269 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
250 intptr_t object_id = SerializedHeaderData::decode(header_value); | 270 intptr_t object_id = SerializedHeaderData::decode(header_value); |
| 271 if (object_id == kOmittedObjectId) { |
| 272 object_id = NextAvailableObjectId(); |
| 273 } |
251 ASSERT(GetBackRef(object_id) == NULL); | 274 ASSERT(GetBackRef(object_id) == NULL); |
252 | 275 |
253 // Read the class header information and lookup the class. | 276 // Read the class header information and lookup the class. |
254 intptr_t class_header = ReadIntptrValue(); | 277 intptr_t class_header = ReadIntptrValue(); |
255 | 278 |
256 // Since we are only reading an object reference, If it is an instance kind | 279 // Since we are only reading an object reference, If it is an instance kind |
257 // then we only need to figure out the class of the object and allocate an | 280 // then we only need to figure out the class of the object and allocate an |
258 // instance of it. The individual fields will be read later. | 281 // instance of it. The individual fields will be read later. |
259 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { | 282 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { |
260 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); | 283 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 ASSERT(class_id == raw->GetClassId()); | 1063 ASSERT(class_id == raw->GetClassId()); |
1041 if (class_id >= kNumPredefinedCids) { | 1064 if (class_id >= kNumPredefinedCids) { |
1042 WriteInstanceRef(raw, cls); | 1065 WriteInstanceRef(raw, cls); |
1043 return; | 1066 return; |
1044 } | 1067 } |
1045 if (class_id == kArrayCid) { | 1068 if (class_id == kArrayCid) { |
1046 // Object is being referenced, add it to the forward ref list and mark | 1069 // Object is being referenced, add it to the forward ref list and mark |
1047 // it so that future references to this object in the snapshot will use | 1070 // it so that future references to this object in the snapshot will use |
1048 // this object id. Mark it as not having been serialized yet so that we | 1071 // this object id. Mark it as not having been serialized yet so that we |
1049 // will serialize the object when we go through the forward list. | 1072 // will serialize the object when we go through the forward list. |
1050 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 1073 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); |
1051 | 1074 |
1052 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 1075 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
1053 | 1076 |
1054 // Write out the serialization header value for this object. | 1077 // Write out the serialization header value for this object. |
1055 WriteInlinedObjectHeader(object_id); | 1078 WriteInlinedObjectHeader(kOmittedObjectId); |
1056 | 1079 |
1057 // Write out the class information. | 1080 // Write out the class information. |
1058 WriteIndexedObject(kArrayCid); | 1081 WriteIndexedObject(kArrayCid); |
1059 | 1082 |
1060 // Write out the length field. | 1083 // Write out the length field. |
1061 Write<RawObject*>(rawarray->ptr()->length_); | 1084 Write<RawObject*>(rawarray->ptr()->length_); |
1062 | 1085 |
1063 return; | 1086 return; |
1064 } | 1087 } |
1065 if (class_id == kImmutableArrayCid) { | 1088 if (class_id == kImmutableArrayCid) { |
1066 // Object is being referenced, add it to the forward ref list and mark | 1089 // Object is being referenced, add it to the forward ref list and mark |
1067 // it so that future references to this object in the snapshot will use | 1090 // it so that future references to this object in the snapshot will use |
1068 // this object id. Mark it as not having been serialized yet so that we | 1091 // this object id. Mark it as not having been serialized yet so that we |
1069 // will serialize the object when we go through the forward list. | 1092 // will serialize the object when we go through the forward list. |
1070 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 1093 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); |
1071 | 1094 |
1072 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 1095 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
1073 | 1096 |
1074 // Write out the serialization header value for this object. | 1097 // Write out the serialization header value for this object. |
1075 WriteInlinedObjectHeader(object_id); | 1098 WriteInlinedObjectHeader(kOmittedObjectId); |
1076 | 1099 |
1077 // Write out the class information. | 1100 // Write out the class information. |
1078 WriteIndexedObject(kImmutableArrayCid); | 1101 WriteIndexedObject(kImmutableArrayCid); |
1079 | 1102 |
1080 // Write out the length field. | 1103 // Write out the length field. |
1081 Write<RawObject*>(rawarray->ptr()->length_); | 1104 Write<RawObject*>(rawarray->ptr()->length_); |
1082 | 1105 |
1083 return; | 1106 return; |
1084 } | 1107 } |
1085 if (RawObject::IsTypedDataViewClassId(class_id)) { | 1108 if (RawObject::IsTypedDataViewClassId(class_id)) { |
1086 WriteInstanceRef(raw, cls); | 1109 WriteInstanceRef(raw, cls); |
1087 return; | 1110 return; |
1088 } | 1111 } |
1089 // Object is being referenced, add it to the forward ref list and mark | 1112 // Object is being referenced, add it to the forward ref list and mark |
1090 // it so that future references to this object in the snapshot will use | 1113 // it so that future references to this object in the snapshot will use |
1091 // this object id. Mark it as not having been serialized yet so that we | 1114 // this object id. Mark it as not having been serialized yet so that we |
1092 // will serialize the object when we go through the forward list. | 1115 // will serialize the object when we go through the forward list. |
1093 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsSerialized); | 1116 forward_list_.MarkAndAddObject(raw, kIsSerialized); |
1094 switch (class_id) { | 1117 switch (class_id) { |
1095 #define SNAPSHOT_WRITE(clazz) \ | 1118 #define SNAPSHOT_WRITE(clazz) \ |
1096 case clazz::kClassId: { \ | 1119 case clazz::kClassId: { \ |
1097 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | 1120 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
1098 raw_obj->WriteTo(this, object_id, kind_); \ | 1121 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ |
1099 return; \ | 1122 return; \ |
1100 } \ | 1123 } \ |
1101 | 1124 |
1102 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | 1125 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
1103 #undef SNAPSHOT_WRITE | 1126 #undef SNAPSHOT_WRITE |
1104 #define SNAPSHOT_WRITE(clazz) \ | 1127 #define SNAPSHOT_WRITE(clazz) \ |
1105 case kTypedData##clazz##Cid: \ | 1128 case kTypedData##clazz##Cid: \ |
1106 | 1129 |
1107 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { | 1130 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
1108 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); | 1131 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); |
1109 raw_obj->WriteTo(this, object_id, kind_); | 1132 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
1110 return; | 1133 return; |
1111 } | 1134 } |
1112 #undef SNAPSHOT_WRITE | 1135 #undef SNAPSHOT_WRITE |
1113 #define SNAPSHOT_WRITE(clazz) \ | 1136 #define SNAPSHOT_WRITE(clazz) \ |
1114 case kExternalTypedData##clazz##Cid: \ | 1137 case kExternalTypedData##clazz##Cid: \ |
1115 | 1138 |
1116 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { | 1139 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
1117 RawExternalTypedData* raw_obj = | 1140 RawExternalTypedData* raw_obj = |
1118 reinterpret_cast<RawExternalTypedData*>(raw); | 1141 reinterpret_cast<RawExternalTypedData*>(raw); |
1119 raw_obj->WriteTo(this, object_id, kind_); | 1142 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
1120 return; | 1143 return; |
1121 } | 1144 } |
1122 #undef SNAPSHOT_WRITE | 1145 #undef SNAPSHOT_WRITE |
1123 default: break; | 1146 default: break; |
1124 } | 1147 } |
1125 UNREACHABLE(); | 1148 UNREACHABLE(); |
1126 } | 1149 } |
1127 | 1150 |
1128 | 1151 |
1129 void FullSnapshotWriter::WriteFullSnapshot() { | 1152 void FullSnapshotWriter::WriteFullSnapshot() { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 // serialized fields of the object | 1334 // serialized fields of the object |
1312 // ...... | 1335 // ...... |
1313 NoGCScope no_gc; | 1336 NoGCScope no_gc; |
1314 uword tags = raw->ptr()->tags_; | 1337 uword tags = raw->ptr()->tags_; |
1315 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1338 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
1316 intptr_t object_id = SerializedHeaderData::decode(tags); | 1339 intptr_t object_id = SerializedHeaderData::decode(tags); |
1317 tags = forward_list_.NodeForObjectId(object_id)->tags(); | 1340 tags = forward_list_.NodeForObjectId(object_id)->tags(); |
1318 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 1341 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
1319 intptr_t class_id = cls->ptr()->id_; | 1342 intptr_t class_id = cls->ptr()->id_; |
1320 | 1343 |
| 1344 if (!IsSplitClassId(class_id)) { |
| 1345 object_id = kOmittedObjectId; |
| 1346 } |
| 1347 |
1321 if (class_id >= kNumPredefinedCids) { | 1348 if (class_id >= kNumPredefinedCids) { |
1322 WriteInstance(object_id, raw, cls, tags); | 1349 WriteInstance(object_id, raw, cls, tags); |
1323 return; | 1350 return; |
1324 } | 1351 } |
1325 switch (class_id) { | 1352 switch (class_id) { |
1326 #define SNAPSHOT_WRITE(clazz) \ | 1353 #define SNAPSHOT_WRITE(clazz) \ |
1327 case clazz::kClassId: { \ | 1354 case clazz::kClassId: { \ |
1328 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | 1355 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
1329 raw_obj->WriteTo(this, object_id, kind_); \ | 1356 raw_obj->WriteTo(this, object_id, kind_); \ |
1330 return; \ | 1357 return; \ |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 | 1550 |
1524 | 1551 |
1525 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { | 1552 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
1526 // First check if object is a closure or has native fields. | 1553 // First check if object is a closure or has native fields. |
1527 CheckIfSerializable(cls); | 1554 CheckIfSerializable(cls); |
1528 | 1555 |
1529 // Object is being referenced, add it to the forward ref list and mark | 1556 // Object is being referenced, add it to the forward ref list and mark |
1530 // it so that future references to this object in the snapshot will use | 1557 // it so that future references to this object in the snapshot will use |
1531 // this object id. Mark it as not having been serialized yet so that we | 1558 // this object id. Mark it as not having been serialized yet so that we |
1532 // will serialize the object when we go through the forward list. | 1559 // will serialize the object when we go through the forward list. |
1533 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 1560 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); |
1534 | 1561 |
1535 // Write out the serialization header value for this object. | 1562 // Write out the serialization header value for this object. |
1536 WriteInlinedObjectHeader(object_id); | 1563 WriteInlinedObjectHeader(kOmittedObjectId); |
1537 | 1564 |
1538 // Indicate this is an instance object. | 1565 // Indicate this is an instance object. |
1539 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1566 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
1540 | 1567 |
1541 // Write out the class information for this object. | 1568 // Write out the class information for this object. |
1542 WriteObjectImpl(cls); | 1569 WriteObjectImpl(cls); |
1543 } | 1570 } |
1544 | 1571 |
1545 | 1572 |
1546 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, | 1573 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 NoGCScope no_gc; | 1632 NoGCScope no_gc; |
1606 WriteObject(obj.raw()); | 1633 WriteObject(obj.raw()); |
1607 UnmarkAll(); | 1634 UnmarkAll(); |
1608 } else { | 1635 } else { |
1609 ThrowException(exception_type(), exception_msg()); | 1636 ThrowException(exception_type(), exception_msg()); |
1610 } | 1637 } |
1611 } | 1638 } |
1612 | 1639 |
1613 | 1640 |
1614 } // namespace dart | 1641 } // namespace dart |
OLD | NEW |