| Index: runtime/vm/snapshot.cc
|
| ===================================================================
|
| --- runtime/vm/snapshot.cc (revision 38170)
|
| +++ runtime/vm/snapshot.cc (working copy)
|
| @@ -942,7 +942,7 @@
|
| kind_(kind),
|
| object_store_(Isolate::Current()->object_store()),
|
| class_table_(Isolate::Current()->class_table()),
|
| - forward_list_(),
|
| + forward_list_(kMaxPredefinedObjectIds),
|
| exception_type_(Exceptions::kNone),
|
| exception_msg_(NULL) {
|
| }
|
| @@ -1047,7 +1047,7 @@
|
| // 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 = MarkObject(raw, kIsNotSerialized);
|
| + intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
|
|
|
| RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
|
|
|
| @@ -1067,7 +1067,7 @@
|
| // 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 = MarkObject(raw, kIsNotSerialized);
|
| + intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
|
|
|
| RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
|
|
|
| @@ -1090,7 +1090,7 @@
|
| // 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 = MarkObject(raw, kIsSerialized);
|
| + intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsSerialized);
|
| switch (class_id) {
|
| #define SNAPSHOT_WRITE(clazz) \
|
| case clazz::kClassId: { \
|
| @@ -1168,16 +1168,16 @@
|
| uword tags = raw->ptr()->tags_;
|
| if (SerializedHeaderTag::decode(tags) == kObjectId) {
|
| intptr_t id = SerializedHeaderData::decode(tags);
|
| - return forward_list_[id - kMaxPredefinedObjectIds]->tags();
|
| + return forward_list_.NodeForObjectId(id)->tags();
|
| } else {
|
| return tags;
|
| }
|
| }
|
|
|
|
|
| -intptr_t SnapshotWriter::MarkObject(RawObject* raw, SerializeState state) {
|
| +intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) {
|
| NoGCScope no_gc;
|
| - intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds;
|
| + intptr_t object_id = next_object_id();
|
| ASSERT(object_id <= kMaxObjectId);
|
| uword value = 0;
|
| value = SerializedHeaderTag::update(kObjectId, value);
|
| @@ -1185,18 +1185,19 @@
|
| uword tags = raw->ptr()->tags_;
|
| ASSERT(SerializedHeaderTag::decode(tags) != kObjectId);
|
| raw->ptr()->tags_ = value;
|
| - ForwardObjectNode* node = new ForwardObjectNode(raw, tags, state);
|
| + Node* node = new Node(raw, tags, state);
|
| ASSERT(node != NULL);
|
| - forward_list_.Add(node);
|
| + nodes_.Add(node);
|
| return object_id;
|
| }
|
|
|
|
|
| -void SnapshotWriter::UnmarkAll() {
|
| +void ForwardList::UnmarkAll() const {
|
| NoGCScope no_gc;
|
| - for (intptr_t i = 0; i < forward_list_.length(); i++) {
|
| - RawObject* raw = forward_list_[i]->raw();
|
| - raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags.
|
| + for (intptr_t id = first_object_id(); id < next_object_id(); ++id) {
|
| + const Node* node = NodeForObjectId(id);
|
| + RawObject* raw = node->raw();
|
| + raw->ptr()->tags_ = node->tags(); // Restore original tags.
|
| }
|
| }
|
|
|
| @@ -1297,7 +1298,7 @@
|
| // Object is being serialized, add it to the forward ref list and mark
|
| // it so that future references to this object in the snapshot will use
|
| // an object id, instead of trying to serialize it again.
|
| - MarkObject(raw, kIsSerialized);
|
| + forward_list_.MarkAndAddObject(raw, kIsSerialized);
|
|
|
| WriteInlinedObject(raw);
|
| }
|
| @@ -1313,7 +1314,7 @@
|
| uword tags = raw->ptr()->tags_;
|
| ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
|
| intptr_t object_id = SerializedHeaderData::decode(tags);
|
| - tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags();
|
| + tags = forward_list_.NodeForObjectId(object_id)->tags();
|
| RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
|
| intptr_t class_id = cls->ptr()->id_;
|
|
|
| @@ -1365,22 +1366,50 @@
|
| }
|
|
|
|
|
| +class WriteInlinedObjectVisitor : public ObjectVisitor {
|
| + public:
|
| + explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
|
| + : ObjectVisitor(Isolate::Current()), writer_(writer) {}
|
| +
|
| + virtual void VisitObject(RawObject* obj) {
|
| + writer_->WriteInlinedObject(obj);
|
| + }
|
| +
|
| + private:
|
| + SnapshotWriter* writer_;
|
| +};
|
| +
|
| +
|
| void SnapshotWriter::WriteForwardedObjects() {
|
| + WriteInlinedObjectVisitor visitor(this);
|
| + forward_list_.SerializeAll(&visitor);
|
| +}
|
| +
|
| +
|
| +void ForwardList::SerializeAll(ObjectVisitor* writer) {
|
| // Write out all objects that were added to the forward list and have
|
| // not been serialized yet. These would typically be fields of instance
|
| // objects, arrays or immutable arrays (this is done in order to avoid
|
| // deep recursive calls to WriteObjectImpl).
|
| // NOTE: The forward list might grow as we process the list.
|
| - for (intptr_t i = 0; i < forward_list_.length(); i++) {
|
| - if (!forward_list_[i]->is_serialized()) {
|
| +#ifdef DEBUG
|
| + for (intptr_t i = first_object_id(); i < first_unprocessed_object_id_; ++i) {
|
| + ASSERT(NodeForObjectId(i)->is_serialized());
|
| + }
|
| +#endif // DEBUG
|
| + for (intptr_t id = first_unprocessed_object_id_;
|
| + id < next_object_id();
|
| + ++id) {
|
| + if (!NodeForObjectId(id)->is_serialized()) {
|
| // Write the object out in the stream.
|
| - RawObject* raw = forward_list_[i]->raw();
|
| - WriteInlinedObject(raw);
|
| + RawObject* raw = NodeForObjectId(id)->raw();
|
| + writer->VisitObject(raw);
|
|
|
| // Mark object as serialized.
|
| - forward_list_[i]->set_state(kIsSerialized);
|
| + NodeForObjectId(id)->set_state(kIsSerialized);
|
| }
|
| }
|
| + first_unprocessed_object_id_ = next_object_id();
|
| }
|
|
|
|
|
| @@ -1501,7 +1530,7 @@
|
| // 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 = MarkObject(raw, kIsNotSerialized);
|
| + intptr_t object_id = forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
|
|
|
| // Write out the serialization header value for this object.
|
| WriteInlinedObjectHeader(object_id);
|
|
|