Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 8c287eb2831ac48c2ce294c3490fc2d4c6909b23..df187945a3d15acff60c8c1efeaaefc79904287f 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -3017,7 +3017,8 @@ void Class::SetFields(const Array& value) const { |
intptr_t len = value.Length(); |
for (intptr_t i = 0; i < len; i++) { |
field ^= value.At(i); |
- ASSERT(field.owner() == raw()); |
+ ASSERT(field.IsOriginal()); |
+ ASSERT(field.Owner() == raw()); |
} |
#endif |
// The value of static fields is already initialized to null. |
@@ -6786,6 +6787,9 @@ void Function::SaveICDataMap( |
void Function::RestoreICDataMap( |
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data, |
bool clone_ic_data) const { |
+ if (FLAG_force_clone_compiler_objects) { |
+ clone_ic_data = true; |
+ } |
ASSERT(deopt_id_to_ic_data->is_empty()); |
Zone* zone = Thread::Current()->zone(); |
const Array& saved_ic_data = Array::Handle(zone, ic_data_array()); |
@@ -6982,6 +6986,31 @@ const char* RedirectionData::ToCString() const { |
} |
+RawField* Field::CloneFromOriginal() const { |
+ return this->Clone(*this); |
+} |
+ |
+ |
+RawField* Field::Original() const { |
+ if (IsNull()) { |
+ return Field::null(); |
+ } |
+ Object& obj = Object::Handle(raw_ptr()->owner_); |
+ if (obj.IsField()) { |
+ return Field::RawCast(obj.raw()); |
+ } else { |
+ return this->raw(); |
+ } |
+} |
+ |
+ |
+void Field::SetOriginal(const Field& value) const { |
+ ASSERT(value.IsOriginal()); |
+ ASSERT(!value.IsNull()); |
+ StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |
+} |
+ |
+ |
RawString* Field::GetterName(const String& field_name) { |
return String::Concat(Symbols::GetterPrefix(), field_name); |
} |
@@ -7036,12 +7065,27 @@ bool Field::IsSetterName(const String& function_name) { |
void Field::set_name(const String& value) const { |
ASSERT(value.IsSymbol()); |
+ ASSERT(IsOriginal()); |
StorePointer(&raw_ptr()->name_, value.raw()); |
} |
-RawClass* Field::owner() const { |
- const Object& obj = Object::Handle(raw_ptr()->owner_); |
+RawObject* Field::RawOwner() const { |
+ if (Original()) { |
+ return raw_ptr()->owner_; |
+ } else { |
+ const Field& field = Field::Handle(Original()); |
+ ASSERT(field.IsOriginal()); |
+ ASSERT(!Object::Handle(field.raw_ptr()->owner_).IsField()); |
+ return field.raw_ptr()->owner_; |
+ } |
+} |
+ |
+ |
+RawClass* Field::Owner() const { |
+ const Field& field = Field::Handle(Original()); |
+ ASSERT(field.IsOriginal()); |
+ const Object& obj = Object::Handle(field.raw_ptr()->owner_); |
if (obj.IsClass()) { |
return Class::Cast(obj).raw(); |
} |
@@ -7050,8 +7094,10 @@ RawClass* Field::owner() const { |
} |
-RawClass* Field::origin() const { |
- const Object& obj = Object::Handle(raw_ptr()->owner_); |
+RawClass* Field::Origin() const { |
+ const Field& field = Field::Handle(Original()); |
+ ASSERT(field.IsOriginal()); |
+ const Object& obj = Object::Handle(field.raw_ptr()->owner_); |
if (obj.IsClass()) { |
return Class::Cast(obj).raw(); |
} |
@@ -7060,8 +7106,10 @@ RawClass* Field::origin() const { |
} |
-RawScript* Field::script() const { |
- const Object& obj = Object::Handle(raw_ptr()->owner_); |
+RawScript* Field::Script() const { |
+ const Field& field = Field::Handle(Original()); |
+ ASSERT(field.IsOriginal()); |
+ const Object& obj = Object::Handle(field.raw_ptr()->owner_); |
if (obj.IsClass()) { |
return Class::Cast(obj).script(); |
} |
@@ -7073,6 +7121,7 @@ RawScript* Field::script() const { |
// Called at finalization time |
void Field::SetFieldType(const AbstractType& value) const { |
ASSERT(Thread::Current()->IsMutatorThread()); |
+ ASSERT(IsOriginal()); |
ASSERT(!value.IsNull()); |
if (value.raw() != type()) { |
StorePointer(&raw_ptr()->type_, value.raw()); |
@@ -7159,7 +7208,7 @@ RawField* Field::NewTopLevel(const String& name, |
RawField* Field::Clone(const Class& new_owner) const { |
Field& clone = Field::Handle(); |
clone ^= Object::Clone(*this, Heap::kOld); |
- const Class& owner = Class::Handle(this->owner()); |
+ const Class& owner = Class::Handle(this->Owner()); |
const PatchClass& clone_owner = |
PatchClass::Handle(PatchClass::New(new_owner, owner)); |
clone.set_owner(clone_owner); |
@@ -7176,6 +7225,18 @@ RawField* Field::Clone(const Class& new_owner) const { |
} |
+RawField* Field::Clone(const Field& original) const { |
+ if (original.IsNull()) { |
+ return Field::null(); |
+ } |
+ ASSERT(original.IsOriginal()); |
+ Field& clone = Field::Handle(); |
+ clone ^= Object::Clone(*this, Heap::kOld); |
+ clone.SetOriginal(original); |
+ return clone.raw(); |
+} |
+ |
+ |
RawString* Field::UserVisibleName() const { |
if (FLAG_show_internal_names) { |
return name(); |
@@ -7191,6 +7252,7 @@ intptr_t Field::guarded_list_length() const { |
void Field::set_guarded_list_length(intptr_t list_length) const { |
ASSERT(Thread::Current()->IsMutatorThread()); |
+ ASSERT(IsOriginal()); |
StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length)); |
} |
@@ -7203,6 +7265,7 @@ intptr_t Field::guarded_list_length_in_object_offset() const { |
void Field::set_guarded_list_length_in_object_offset( |
intptr_t list_length_offset) const { |
ASSERT(Thread::Current()->IsMutatorThread()); |
+ ASSERT(IsOriginal()); |
StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_, |
static_cast<int8_t>(list_length_offset - kHeapObjectTag)); |
ASSERT(guarded_list_length_in_object_offset() == list_length_offset); |
@@ -7217,7 +7280,7 @@ const char* Field::ToCString() const { |
const char* kF1 = is_final() ? " final" : ""; |
const char* kF2 = is_const() ? " const" : ""; |
const char* field_name = String::Handle(name()).ToCString(); |
- const Class& cls = Class::Handle(owner()); |
+ const Class& cls = Class::Handle(Owner()); |
const char* cls_name = String::Handle(cls.Name()).ToCString(); |
return OS::SCreate(Thread::Current()->zone(), |
"Field <%s.%s>:%s%s%s", cls_name, field_name, kF0, kF1, kF2); |
@@ -7229,7 +7292,7 @@ const char* Field::ToCString() const { |
// named #f (or #f= in case of a setter). |
RawInstance* Field::AccessorClosure(bool make_setter) const { |
ASSERT(is_static()); |
- const Class& field_owner = Class::Handle(owner()); |
+ const Class& field_owner = Class::Handle(Owner()); |
String& closure_name = String::Handle(this->name()); |
closure_name = Symbols::FromConcat(Symbols::HashMark(), closure_name); |
@@ -7299,6 +7362,7 @@ RawArray* Field::dependent_code() const { |
void Field::set_dependent_code(const Array& array) const { |
+ ASSERT(IsOriginal()); |
StorePointer(&raw_ptr()->dependent_code_, array.raw()); |
} |
@@ -7342,6 +7406,7 @@ class FieldDependentArray : public WeakCodeReferences { |
void Field::RegisterDependentCode(const Code& code) const { |
+ ASSERT(IsOriginal()); |
DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
ASSERT(code.is_optimized()); |
FieldDependentArray a(*this); |
@@ -7350,6 +7415,7 @@ void Field::RegisterDependentCode(const Code& code) const { |
void Field::DeoptimizeDependentCode() const { |
+ ASSERT(IsOriginal()); |
ASSERT(Thread::Current()->IsMutatorThread()); |
FieldDependentArray a(*this); |
a.DisableCode(); |
@@ -7364,6 +7430,7 @@ bool Field::IsUninitialized() const { |
void Field::SetPrecompiledInitializer(const Function& initializer) const { |
+ ASSERT(IsOriginal()); |
StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw()); |
} |
@@ -7375,12 +7442,14 @@ bool Field::HasPrecompiledInitializer() const { |
void Field::SetSavedInitialStaticValue(const Instance& value) const { |
+ ASSERT(IsOriginal()); |
ASSERT(!HasPrecompiledInitializer()); |
StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw()); |
} |
void Field::EvaluateInitializer() const { |
+ ASSERT(IsOriginal()); |
ASSERT(is_static()); |
if (StaticValue() == Object::sentinel().raw()) { |
SetStaticValue(Object::transition_sentinel()); |
@@ -7482,6 +7551,7 @@ const char* Field::GuardedPropertiesAsCString() const { |
void Field::InitializeGuardedListLengthInObjectOffset() const { |
+ ASSERT(IsOriginal()); |
if (needs_length_check() && |
(guarded_list_length() != Field::kUnknownFixedLength)) { |
const intptr_t offset = GetListLengthOffset(guarded_cid()); |
@@ -7494,6 +7564,7 @@ void Field::InitializeGuardedListLengthInObjectOffset() const { |
bool Field::UpdateGuardedCidAndLength(const Object& value) const { |
+ ASSERT(IsOriginal()); |
const intptr_t cid = value.GetClassId(); |
if (guarded_cid() == kIllegalCid) { |
@@ -7561,6 +7632,7 @@ bool Field::UpdateGuardedCidAndLength(const Object& value) const { |
void Field::RecordStore(const Object& value) const { |
+ ASSERT(IsOriginal()); |
if (!FLAG_use_field_guards) { |
return; |
} |
@@ -8922,7 +8994,7 @@ static RawString* MakeClassMetaName(const Class& cls) { |
static RawString* MakeFieldMetaName(const Field& field) { |
const String& cname = |
- String::Handle(MakeClassMetaName(Class::Handle(field.origin()))); |
+ String::Handle(MakeClassMetaName(Class::Handle(field.Origin()))); |
GrowableHandlePtrArray<const String> pieces(Thread::Current()->zone(), 3); |
pieces.Add(cname); |
pieces.Add(Symbols::At()); |
@@ -9387,7 +9459,7 @@ RawArray* Library::LoadedScripts() const { |
} else if (entry.IsFunction()) { |
owner_script = Function::Cast(entry).script(); |
} else if (entry.IsField()) { |
- owner_script = Field::Cast(entry).script(); |
+ owner_script = Field::Cast(entry).Script(); |
} else { |
continue; |
} |