Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: runtime/vm/snapshot.cc

Issue 387993007: 5% smaller snapshots by omitting object ids when possible (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_ids.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_ids.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698