| Index: runtime/vm/clustered_snapshot.cc
|
| diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
|
| index 8b6eb0a975b9cf237d9ce6f9daaa8db36c3e8dd1..11d9dd050935b76e8347b12e12a45f2de8e12989 100644
|
| --- a/runtime/vm/clustered_snapshot.cc
|
| +++ b/runtime/vm/clustered_snapshot.cc
|
| @@ -114,8 +114,7 @@ class ClassSerializationCluster : public SerializationCluster {
|
| }
|
| intptr_t class_id = cls->ptr()->id_;
|
| if (class_id == kIllegalCid) {
|
| - FATAL1("Attempting to serialize class with illegal cid: %s\n",
|
| - Class::Handle(cls).ToCString());
|
| + s->UnexpectedObject(cls, "Class with illegal cid");
|
| }
|
| s->WriteCid(class_id);
|
| s->Write<int32_t>(cls->ptr()->instance_size_in_words_);
|
| @@ -4504,7 +4503,13 @@ Serializer::Serializer(Thread* thread,
|
| num_cids_(0),
|
| num_base_objects_(0),
|
| num_written_objects_(0),
|
| - next_ref_index_(1) {
|
| + next_ref_index_(1)
|
| +#if defined(SNAPSHOT_BACKTRACE)
|
| + ,
|
| + current_parent_(Object::null()),
|
| + parent_pairs_()
|
| +#endif
|
| +{
|
| num_cids_ = thread->isolate()->class_table()->NumCids();
|
| clusters_by_cid_ = new SerializationCluster*[num_cids_];
|
| for (intptr_t i = 0; i < num_cids_; i++) {
|
| @@ -4649,6 +4654,45 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
|
| }
|
|
|
|
|
| +void Serializer::Push(RawObject* object) {
|
| + if (!object->IsHeapObject()) {
|
| + RawSmi* smi = Smi::RawCast(object);
|
| + if (smi_ids_.Lookup(smi) == NULL) {
|
| + SmiObjectIdPair pair;
|
| + pair.smi_ = smi;
|
| + pair.id_ = 1;
|
| + smi_ids_.Insert(pair);
|
| + stack_.Add(object);
|
| + num_written_objects_++;
|
| + }
|
| + return;
|
| + }
|
| +
|
| + if (object->IsCode() && !Snapshot::IncludesCode(kind_)) {
|
| + return; // Do not trace, will write null.
|
| + }
|
| +
|
| + if (object->IsSendPort()) {
|
| + // TODO(rmacnak): Do a better job of resetting fields in precompilation
|
| + // and assert this is unreachable.
|
| + return; // Do not trace, will write null.
|
| + }
|
| +
|
| + intptr_t id = heap_->GetObjectId(object);
|
| + if (id == 0) {
|
| + heap_->SetObjectId(object, 1);
|
| + ASSERT(heap_->GetObjectId(object) != 0);
|
| + stack_.Add(object);
|
| + num_written_objects_++;
|
| +
|
| +#if defined(SNAPSHOT_BACKTRACE)
|
| + parent_pairs_.Add(&Object::Handle(object));
|
| + parent_pairs_.Add(&Object::Handle(current_parent_));
|
| +#endif
|
| + }
|
| +}
|
| +
|
| +
|
| void Serializer::Trace(RawObject* object) {
|
| intptr_t cid;
|
| if (!object->IsHeapObject()) {
|
| @@ -4665,8 +4709,42 @@ void Serializer::Trace(RawObject* object) {
|
| clusters_by_cid_[cid] = cluster;
|
| }
|
| ASSERT(cluster != NULL);
|
| +
|
| +#if defined(SNAPSHOT_BACKTRACE)
|
| + current_parent_ = object;
|
| +#endif
|
| +
|
| cluster->Trace(this, object);
|
| +
|
| +#if defined(SNAPSHOT_BACKTRACE)
|
| + current_parent_ = Object::null();
|
| +#endif
|
| +}
|
| +
|
| +
|
| +void Serializer::UnexpectedObject(RawObject* raw_object, const char* message) {
|
| + Object& object = Object::Handle(raw_object);
|
| + OS::PrintErr("Unexpected object (%s): %s\n", message, object.ToCString());
|
| +#if defined(SNAPSHOT_BACKTRACE)
|
| + while (!object.IsNull()) {
|
| + object = ParentOf(object);
|
| + OS::PrintErr("referenced by %s\n", object.ToCString());
|
| + }
|
| +#endif
|
| + OS::Abort();
|
| +}
|
| +
|
| +
|
| +#if defined(SNAPSHOT_BACKTRACE)
|
| +RawObject* Serializer::ParentOf(const Object& object) {
|
| + for (intptr_t i = 0; i < parent_pairs_.length(); i += 2) {
|
| + if (parent_pairs_[i]->raw() == object.raw()) {
|
| + return parent_pairs_[i + 1]->raw();
|
| + }
|
| + }
|
| + return Object::null();
|
| }
|
| +#endif // SNAPSHOT_BACKTRACE
|
|
|
|
|
| void Serializer::WriteVersionAndFeatures() {
|
|
|