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