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

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

Issue 383063005: Refactor snapshot writer's forward list into a reusable class. (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') | no next file » | 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 924 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 935
936 936
937 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, 937 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind,
938 uint8_t** buffer, 938 uint8_t** buffer,
939 ReAlloc alloc, 939 ReAlloc alloc,
940 intptr_t initial_size) 940 intptr_t initial_size)
941 : BaseWriter(buffer, alloc, initial_size), 941 : BaseWriter(buffer, alloc, initial_size),
942 kind_(kind), 942 kind_(kind),
943 object_store_(Isolate::Current()->object_store()), 943 object_store_(Isolate::Current()->object_store()),
944 class_table_(Isolate::Current()->class_table()), 944 class_table_(Isolate::Current()->class_table()),
945 forward_list_(), 945 forward_list_(kMaxPredefinedObjectIds),
946 exception_type_(Exceptions::kNone), 946 exception_type_(Exceptions::kNone),
947 exception_msg_(NULL) { 947 exception_msg_(NULL) {
948 } 948 }
949 949
950 950
951 void SnapshotWriter::WriteObject(RawObject* rawobj) { 951 void SnapshotWriter::WriteObject(RawObject* rawobj) {
952 WriteObjectImpl(rawobj); 952 WriteObjectImpl(rawobj);
953 WriteForwardedObjects(); 953 WriteForwardedObjects();
954 } 954 }
955 955
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 ASSERT(class_id == raw->GetClassId()); 1040 ASSERT(class_id == raw->GetClassId());
1041 if (class_id >= kNumPredefinedCids) { 1041 if (class_id >= kNumPredefinedCids) {
1042 WriteInstanceRef(raw, cls); 1042 WriteInstanceRef(raw, cls);
1043 return; 1043 return;
1044 } 1044 }
1045 if (class_id == kArrayCid) { 1045 if (class_id == kArrayCid) {
1046 // Object is being referenced, add it to the forward ref list and mark 1046 // 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 1047 // 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 1048 // 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. 1049 // will serialize the object when we go through the forward list.
1050 intptr_t object_id = MarkObject(raw, kIsNotSerialized); 1050 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
1051 1051
1052 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); 1052 RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
1053 1053
1054 // Write out the serialization header value for this object. 1054 // Write out the serialization header value for this object.
1055 WriteInlinedObjectHeader(object_id); 1055 WriteInlinedObjectHeader(object_id);
1056 1056
1057 // Write out the class information. 1057 // Write out the class information.
1058 WriteIndexedObject(kArrayCid); 1058 WriteIndexedObject(kArrayCid);
1059 1059
1060 // Write out the length field. 1060 // Write out the length field.
1061 Write<RawObject*>(rawarray->ptr()->length_); 1061 Write<RawObject*>(rawarray->ptr()->length_);
1062 1062
1063 return; 1063 return;
1064 } 1064 }
1065 if (class_id == kImmutableArrayCid) { 1065 if (class_id == kImmutableArrayCid) {
1066 // Object is being referenced, add it to the forward ref list and mark 1066 // 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 1067 // 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 1068 // 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. 1069 // will serialize the object when we go through the forward list.
1070 intptr_t object_id = MarkObject(raw, kIsNotSerialized); 1070 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
1071 1071
1072 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); 1072 RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
1073 1073
1074 // Write out the serialization header value for this object. 1074 // Write out the serialization header value for this object.
1075 WriteInlinedObjectHeader(object_id); 1075 WriteInlinedObjectHeader(object_id);
1076 1076
1077 // Write out the class information. 1077 // Write out the class information.
1078 WriteIndexedObject(kImmutableArrayCid); 1078 WriteIndexedObject(kImmutableArrayCid);
1079 1079
1080 // Write out the length field. 1080 // Write out the length field.
1081 Write<RawObject*>(rawarray->ptr()->length_); 1081 Write<RawObject*>(rawarray->ptr()->length_);
1082 1082
1083 return; 1083 return;
1084 } 1084 }
1085 if (RawObject::IsTypedDataViewClassId(class_id)) { 1085 if (RawObject::IsTypedDataViewClassId(class_id)) {
1086 WriteInstanceRef(raw, cls); 1086 WriteInstanceRef(raw, cls);
1087 return; 1087 return;
1088 } 1088 }
1089 // 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
1090 // 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
1091 // 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
1092 // will serialize the object when we go through the forward list. 1092 // will serialize the object when we go through the forward list.
1093 intptr_t object_id = MarkObject(raw, kIsSerialized); 1093 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsSerialized);
1094 switch (class_id) { 1094 switch (class_id) {
1095 #define SNAPSHOT_WRITE(clazz) \ 1095 #define SNAPSHOT_WRITE(clazz) \
1096 case clazz::kClassId: { \ 1096 case clazz::kClassId: { \
1097 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ 1097 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
1098 raw_obj->WriteTo(this, object_id, kind_); \ 1098 raw_obj->WriteTo(this, object_id, kind_); \
1099 return; \ 1099 return; \
1100 } \ 1100 } \
1101 1101
1102 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) 1102 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
1103 #undef SNAPSHOT_WRITE 1103 #undef SNAPSHOT_WRITE
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 } else { 1161 } else {
1162 ThrowException(exception_type(), exception_msg()); 1162 ThrowException(exception_type(), exception_msg());
1163 } 1163 }
1164 } 1164 }
1165 1165
1166 1166
1167 uword SnapshotWriter::GetObjectTags(RawObject* raw) { 1167 uword SnapshotWriter::GetObjectTags(RawObject* raw) {
1168 uword tags = raw->ptr()->tags_; 1168 uword tags = raw->ptr()->tags_;
1169 if (SerializedHeaderTag::decode(tags) == kObjectId) { 1169 if (SerializedHeaderTag::decode(tags) == kObjectId) {
1170 intptr_t id = SerializedHeaderData::decode(tags); 1170 intptr_t id = SerializedHeaderData::decode(tags);
1171 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); 1171 return forward_list_.NodeForObjectId(id)->tags();
1172 } else { 1172 } else {
1173 return tags; 1173 return tags;
1174 } 1174 }
1175 } 1175 }
1176 1176
1177 1177
1178 intptr_t SnapshotWriter::MarkObject(RawObject* raw, SerializeState state) { 1178 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) {
1179 NoGCScope no_gc; 1179 NoGCScope no_gc;
1180 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; 1180 intptr_t object_id = next_object_id();
1181 ASSERT(object_id <= kMaxObjectId); 1181 ASSERT(object_id <= kMaxObjectId);
1182 uword value = 0; 1182 uword value = 0;
1183 value = SerializedHeaderTag::update(kObjectId, value); 1183 value = SerializedHeaderTag::update(kObjectId, value);
1184 value = SerializedHeaderData::update(object_id, value); 1184 value = SerializedHeaderData::update(object_id, value);
1185 uword tags = raw->ptr()->tags_; 1185 uword tags = raw->ptr()->tags_;
1186 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); 1186 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId);
1187 raw->ptr()->tags_ = value; 1187 raw->ptr()->tags_ = value;
1188 ForwardObjectNode* node = new ForwardObjectNode(raw, tags, state); 1188 Node* node = new Node(raw, tags, state);
1189 ASSERT(node != NULL); 1189 ASSERT(node != NULL);
1190 forward_list_.Add(node); 1190 nodes_.Add(node);
1191 return object_id; 1191 return object_id;
1192 } 1192 }
1193 1193
1194 1194
1195 void SnapshotWriter::UnmarkAll() { 1195 void ForwardList::UnmarkAll() const {
1196 NoGCScope no_gc; 1196 NoGCScope no_gc;
1197 for (intptr_t i = 0; i < forward_list_.length(); i++) { 1197 for (intptr_t id = first_object_id(); id < next_object_id(); ++id) {
1198 RawObject* raw = forward_list_[i]->raw(); 1198 const Node* node = NodeForObjectId(id);
1199 raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags. 1199 RawObject* raw = node->raw();
1200 raw->ptr()->tags_ = node->tags(); // Restore original tags.
1200 } 1201 }
1201 } 1202 }
1202 1203
1203 1204
1204 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { 1205 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) {
1205 // Check if object can be written in one of the following ways: 1206 // Check if object can be written in one of the following ways:
1206 // - Smi: the Smi value is written as is (last bit is not tagged). 1207 // - Smi: the Smi value is written as is (last bit is not tagged).
1207 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) 1208 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3)
1208 // - Object that has already been written: (negative id in stream | 0x3) 1209 // - Object that has already been written: (negative id in stream | 0x3)
1209 1210
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 1291
1291 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { 1292 void SnapshotWriter::WriteObjectImpl(RawObject* raw) {
1292 // First check if object can be written as a simple predefined type. 1293 // First check if object can be written as a simple predefined type.
1293 if (CheckAndWritePredefinedObject(raw)) { 1294 if (CheckAndWritePredefinedObject(raw)) {
1294 return; 1295 return;
1295 } 1296 }
1296 1297
1297 // Object is being serialized, add it to the forward ref list and mark 1298 // Object is being serialized, add it to the forward ref list and mark
1298 // it so that future references to this object in the snapshot will use 1299 // it so that future references to this object in the snapshot will use
1299 // an object id, instead of trying to serialize it again. 1300 // an object id, instead of trying to serialize it again.
1300 MarkObject(raw, kIsSerialized); 1301 forward_list_.MarkAndAddObject(raw, kIsSerialized);
1301 1302
1302 WriteInlinedObject(raw); 1303 WriteInlinedObject(raw);
1303 } 1304 }
1304 1305
1305 1306
1306 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { 1307 void SnapshotWriter::WriteInlinedObject(RawObject* raw) {
1307 // Now write the object out inline in the stream as follows: 1308 // Now write the object out inline in the stream as follows:
1308 // - Object is seen for the first time (inlined as follows): 1309 // - Object is seen for the first time (inlined as follows):
1309 // (object size in multiples of kObjectAlignment | 0x1) 1310 // (object size in multiples of kObjectAlignment | 0x1)
1310 // serialized fields of the object 1311 // serialized fields of the object
1311 // ...... 1312 // ......
1312 NoGCScope no_gc; 1313 NoGCScope no_gc;
1313 uword tags = raw->ptr()->tags_; 1314 uword tags = raw->ptr()->tags_;
1314 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); 1315 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
1315 intptr_t object_id = SerializedHeaderData::decode(tags); 1316 intptr_t object_id = SerializedHeaderData::decode(tags);
1316 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); 1317 tags = forward_list_.NodeForObjectId(object_id)->tags();
1317 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); 1318 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
1318 intptr_t class_id = cls->ptr()->id_; 1319 intptr_t class_id = cls->ptr()->id_;
1319 1320
1320 if (class_id >= kNumPredefinedCids) { 1321 if (class_id >= kNumPredefinedCids) {
1321 WriteInstance(object_id, raw, cls, tags); 1322 WriteInstance(object_id, raw, cls, tags);
1322 return; 1323 return;
1323 } 1324 }
1324 switch (class_id) { 1325 switch (class_id) {
1325 #define SNAPSHOT_WRITE(clazz) \ 1326 #define SNAPSHOT_WRITE(clazz) \
1326 case clazz::kClassId: { \ 1327 case clazz::kClassId: { \
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 WriteInstance(object_id, raw, cls, tags); 1359 WriteInstance(object_id, raw, cls, tags);
1359 return; 1360 return;
1360 } 1361 }
1361 #undef SNAPSHOT_WRITE 1362 #undef SNAPSHOT_WRITE
1362 default: break; 1363 default: break;
1363 } 1364 }
1364 UNREACHABLE(); 1365 UNREACHABLE();
1365 } 1366 }
1366 1367
1367 1368
1369 class WriteInlinedObjectVisitor : public ObjectVisitor {
1370 public:
1371 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
1372 : ObjectVisitor(Isolate::Current()), writer_(writer) {}
1373
1374 virtual void VisitObject(RawObject* obj) {
1375 writer_->WriteInlinedObject(obj);
1376 }
1377
1378 private:
1379 SnapshotWriter* writer_;
1380 };
1381
1382
1368 void SnapshotWriter::WriteForwardedObjects() { 1383 void SnapshotWriter::WriteForwardedObjects() {
1384 WriteInlinedObjectVisitor visitor(this);
1385 forward_list_.SerializeAll(&visitor);
1386 }
1387
1388
1389 void ForwardList::SerializeAll(ObjectVisitor* writer) {
1369 // Write out all objects that were added to the forward list and have 1390 // Write out all objects that were added to the forward list and have
1370 // not been serialized yet. These would typically be fields of instance 1391 // not been serialized yet. These would typically be fields of instance
1371 // objects, arrays or immutable arrays (this is done in order to avoid 1392 // objects, arrays or immutable arrays (this is done in order to avoid
1372 // deep recursive calls to WriteObjectImpl). 1393 // deep recursive calls to WriteObjectImpl).
1373 // NOTE: The forward list might grow as we process the list. 1394 // NOTE: The forward list might grow as we process the list.
1374 for (intptr_t i = 0; i < forward_list_.length(); i++) { 1395 #ifdef DEBUG
1375 if (!forward_list_[i]->is_serialized()) { 1396 for (intptr_t i = first_object_id(); i < first_unprocessed_object_id_; ++i) {
1397 ASSERT(NodeForObjectId(i)->is_serialized());
1398 }
1399 #endif // DEBUG
1400 for (intptr_t id = first_unprocessed_object_id_;
1401 id < next_object_id();
1402 ++id) {
1403 if (!NodeForObjectId(id)->is_serialized()) {
1376 // Write the object out in the stream. 1404 // Write the object out in the stream.
1377 RawObject* raw = forward_list_[i]->raw(); 1405 RawObject* raw = NodeForObjectId(id)->raw();
1378 WriteInlinedObject(raw); 1406 writer->VisitObject(raw);
1379 1407
1380 // Mark object as serialized. 1408 // Mark object as serialized.
1381 forward_list_[i]->set_state(kIsSerialized); 1409 NodeForObjectId(id)->set_state(kIsSerialized);
1382 } 1410 }
1383 } 1411 }
1412 first_unprocessed_object_id_ = next_object_id();
1384 } 1413 }
1385 1414
1386 1415
1387 void SnapshotWriter::WriteClassId(RawClass* cls) { 1416 void SnapshotWriter::WriteClassId(RawClass* cls) {
1388 ASSERT(kind_ != Snapshot::kFull); 1417 ASSERT(kind_ != Snapshot::kFull);
1389 int class_id = cls->ptr()->id_; 1418 int class_id = cls->ptr()->id_;
1390 ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id)); 1419 ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id));
1391 // TODO(5411462): Should restrict this to only core-lib classes in this 1420 // TODO(5411462): Should restrict this to only core-lib classes in this
1392 // case. 1421 // case.
1393 // Write out the class and tags information. 1422 // Write out the class and tags information.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 1523
1495 1524
1496 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { 1525 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) {
1497 // First check if object is a closure or has native fields. 1526 // First check if object is a closure or has native fields.
1498 CheckIfSerializable(cls); 1527 CheckIfSerializable(cls);
1499 1528
1500 // Object is being referenced, add it to the forward ref list and mark 1529 // Object is being referenced, add it to the forward ref list and mark
1501 // it so that future references to this object in the snapshot will use 1530 // it so that future references to this object in the snapshot will use
1502 // this object id. Mark it as not having been serialized yet so that we 1531 // this object id. Mark it as not having been serialized yet so that we
1503 // will serialize the object when we go through the forward list. 1532 // will serialize the object when we go through the forward list.
1504 intptr_t object_id = MarkObject(raw, kIsNotSerialized); 1533 intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
1505 1534
1506 // Write out the serialization header value for this object. 1535 // Write out the serialization header value for this object.
1507 WriteInlinedObjectHeader(object_id); 1536 WriteInlinedObjectHeader(object_id);
1508 1537
1509 // Indicate this is an instance object. 1538 // Indicate this is an instance object.
1510 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); 1539 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId));
1511 1540
1512 // Write out the class information for this object. 1541 // Write out the class information for this object.
1513 WriteObjectImpl(cls); 1542 WriteObjectImpl(cls);
1514 } 1543 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 NoGCScope no_gc; 1605 NoGCScope no_gc;
1577 WriteObject(obj.raw()); 1606 WriteObject(obj.raw());
1578 UnmarkAll(); 1607 UnmarkAll();
1579 } else { 1608 } else {
1580 ThrowException(exception_type(), exception_msg()); 1609 ThrowException(exception_type(), exception_msg());
1581 } 1610 }
1582 } 1611 }
1583 1612
1584 1613
1585 } // namespace dart 1614 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698