diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc index ab9e6cdc61a..3632b92b877 100644 --- a/runtime/vm/deferred_objects.cc +++ b/runtime/vm/deferred_objects.cc @@ -116,12 +116,22 @@ void DeferredObject::Materialize() { const Instance& obj = Instance::ZoneHandle(Instance::New(cls)); + Smi& offset = Smi::Handle(); Field& field = Field::Handle(); Object& value = Object::Handle(); + const Array& offset_map = Array::Handle(cls.OffsetToFieldMap()); + for (intptr_t i = 0; i < field_count_; i++) { - field ^= GetField(i); + offset ^= GetFieldOffset(i); + field ^= offset_map.At(offset.Value() / kWordSize); value = GetValue(i); - obj.SetField(field, value); + if (!field.IsNull()) { + obj.SetField(field, value); + } else { + ASSERT(cls.IsSignatureClass() || + (offset.Value() == cls.type_arguments_field_offset())); + obj.SetFieldAtOffset(offset.Value(), value); + } if (FLAG_trace_deoptimization_verbose) { OS::PrintErr(" %s <- %s\n", diff --git a/runtime/vm/deferred_objects.h b/runtime/vm/deferred_objects.h index 2e0733c4c9a..9619d16e5ab 100644 --- a/runtime/vm/deferred_objects.h +++ b/runtime/vm/deferred_objects.h @@ -164,7 +164,7 @@ class DeferredObject { }; enum { - kFieldIndex = 0, + kOffsetIndex = 0, kValueIndex, kFieldEntrySize, }; @@ -178,8 +178,8 @@ class DeferredObject { return args_[kClassIndex]; } - RawObject* GetField(intptr_t index) const { - return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex]; + RawObject* GetFieldOffset(intptr_t index) const { + return args_[kFieldsStartIndex + kFieldEntrySize * index + kOffsetIndex]; } RawObject* GetValue(intptr_t index) const { diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc index 9dca795b39a..14ca863d449 100644 --- a/runtime/vm/deopt_instructions.cc +++ b/runtime/vm/deopt_instructions.cc @@ -1377,8 +1377,9 @@ intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) { AddConstant(mat->cls(), dest_index++); for (intptr_t i = 0; i < mat->InputCount(); i++) { if (!mat->InputAt(i)->BindsToConstantNull()) { - // Emit field-value pair. - AddConstant(mat->FieldAt(i), dest_index++); + // Emit offset-value pair. + AddConstant(Smi::Handle(Smi::New(mat->FieldOffsetAt(i))), + dest_index++); AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++); } } diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h index 880408840b1..117a816eb86 100644 --- a/runtime/vm/intermediate_language.h +++ b/runtime/vm/intermediate_language.h @@ -4073,8 +4073,8 @@ class MaterializeObjectInstr : public Definition { } const Class& cls() const { return cls_; } - const Field& FieldAt(intptr_t i) const { - return *fields_[i]; + intptr_t FieldOffsetAt(intptr_t i) const { + return fields_[i]->Offset(); } const Location& LocationAt(intptr_t i) { return locations_[i]; diff --git a/runtime/vm/object.h b/runtime/vm/object.h index ddd5ce162d0..3747a39664b 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -4060,6 +4060,7 @@ class Instance : public Object { friend class SnapshotWriter; friend class StubCode; friend class TypedDataView; + friend class DeferredObject; };