diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc index 33ffe72b107..10518a894ab 100644 --- a/runtime/vm/code_patcher_arm64.cc +++ b/runtime/vm/code_patcher_arm64.cc @@ -29,7 +29,7 @@ class PoolPointerCall : public ValueObject { } void SetTarget(const Code& target) const { - object_pool_.SetObjectAt(pp_index(), target); + object_pool_.SetObjectAt(pp_index(), target); // No need to flush the instruction cache, since the code is not modified. } diff --git a/runtime/vm/code_patcher_riscv.cc b/runtime/vm/code_patcher_riscv.cc index daa99fe6349..b85d165fa2e 100644 --- a/runtime/vm/code_patcher_riscv.cc +++ b/runtime/vm/code_patcher_riscv.cc @@ -39,7 +39,7 @@ class PoolPointerCall : public ValueObject { } void SetTarget(const Code& target) const { - object_pool_.SetObjectAt(pp_index(), target); + object_pool_.SetObjectAt(pp_index(), target); // No need to flush the instruction cache, since the code is not modified. } diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc index a6404a32ac3..32dcecd26e1 100644 --- a/runtime/vm/code_patcher_x64.cc +++ b/runtime/vm/code_patcher_x64.cc @@ -147,7 +147,7 @@ class UnoptimizedCall : public ValueObject { } void set_target(const Code& target) const { - object_pool_.SetObjectAt(code_index_, target); + object_pool_.SetObjectAt(code_index_, target); // No need to flush the instruction cache, since the code is not modified. } @@ -181,7 +181,8 @@ class NativeCall : public ValueObject { } void set_native_function(NativeFunction func) const { - object_pool_.SetRawValueAt(argument_index(), reinterpret_cast(func)); + object_pool_.SetRawValueAt( + argument_index(), reinterpret_cast(func)); } CodePtr target() const { @@ -191,7 +192,7 @@ class NativeCall : public ValueObject { } void set_target(const Code& target) const { - object_pool_.SetObjectAt(code_index_, target); + object_pool_.SetObjectAt(code_index_, target); // No need to flush the instruction cache, since the code is not modified. } @@ -220,7 +221,7 @@ class InstanceCall : public UnoptimizedCall { ObjectPtr data() const { return object_pool_.ObjectAt(argument_index()); } void set_data(const Object& data) const { ASSERT(data.IsArray() || data.IsICData() || data.IsMegamorphicCache()); - object_pool_.SetObjectAt(argument_index(), data); + object_pool_.SetObjectAt(argument_index(), data); } private: @@ -265,7 +266,7 @@ class PoolPointerCall : public ValueObject { } void SetTarget(const Code& target) const { - object_pool_.SetObjectAt(code_index_, target); + object_pool_.SetObjectAt(code_index_, target); // No need to flush the instruction cache, since the code is not modified. } @@ -294,7 +295,7 @@ class SwitchableCallBase : public ValueObject { void SetData(const Object& data) const { ASSERT(!Object::Handle(object_pool_.ObjectAt(data_index())).IsCode()); - object_pool_.SetObjectAt(data_index(), data); + object_pool_.SetObjectAt(data_index(), data); // No need to flush the instruction cache, since the code is not modified. } @@ -353,7 +354,7 @@ class SwitchableCall : public SwitchableCallBase { void SetTarget(const Code& target) const { ASSERT(Object::Handle(object_pool_.ObjectAt(target_index())).IsCode()); - object_pool_.SetObjectAt(target_index(), target); + object_pool_.SetObjectAt(target_index(), target); // No need to flush the instruction cache, since the code is not modified. } @@ -424,7 +425,8 @@ class BareSwitchableCall : public SwitchableCallBase { void SetTarget(const Code& target) const { ASSERT(object_pool_.TypeAt(target_index()) == ObjectPool::EntryType::kImmediate); - object_pool_.SetRawValueAt(target_index(), target.MonomorphicEntryPoint()); + object_pool_.SetRawValueAt( + target_index(), target.MonomorphicEntryPoint()); } uword target_entry() const { return object_pool_.RawValueAt(target_index()); } diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc index e86c3816cd6..205f86e3717 100644 --- a/runtime/vm/instructions_arm.cc +++ b/runtime/vm/instructions_arm.cc @@ -75,7 +75,8 @@ CodePtr NativeCallPattern::target() const { } void NativeCallPattern::set_target(const Code& new_target) const { - object_pool_.SetObjectAt(target_code_pool_index_, new_target); + object_pool_.SetObjectAt(target_code_pool_index_, + new_target); // No need to flush the instruction cache, since the code is not modified. } @@ -85,8 +86,8 @@ NativeFunction NativeCallPattern::native_function() const { } void NativeCallPattern::set_native_function(NativeFunction func) const { - object_pool_.SetRawValueAt(native_function_pool_index_, - reinterpret_cast(func)); + object_pool_.SetRawValueAt( + native_function_pool_index_, reinterpret_cast(func)); } // Decodes a load sequence ending at 'end' (the last instruction of the load @@ -216,7 +217,8 @@ CodePtr CallPattern::TargetCode() const { } void CallPattern::SetTargetCode(const Code& target_code) const { - object_pool_.SetObjectAt(target_code_pool_index_, target_code); + object_pool_.SetObjectAt(target_code_pool_index_, + target_code); } ObjectPtr ICCallPattern::Data() const { @@ -225,7 +227,7 @@ ObjectPtr ICCallPattern::Data() const { void ICCallPattern::SetData(const Object& data) const { ASSERT(data.IsArray() || data.IsICData() || data.IsMegamorphicCache()); - object_pool_.SetObjectAt(data_pool_index_, data); + object_pool_.SetObjectAt(data_pool_index_, data); } CodePtr ICCallPattern::TargetCode() const { @@ -233,7 +235,8 @@ CodePtr ICCallPattern::TargetCode() const { } void ICCallPattern::SetTargetCode(const Code& target_code) const { - object_pool_.SetObjectAt(target_pool_index_, target_code); + object_pool_.SetObjectAt(target_pool_index_, + target_code); } SwitchableCallPatternBase::SwitchableCallPatternBase( @@ -246,7 +249,7 @@ ObjectPtr SwitchableCallPatternBase::data() const { void SwitchableCallPatternBase::SetData(const Object& data) const { ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); - object_pool_.SetObjectAt(data_pool_index_, data); + object_pool_.SetObjectAt(data_pool_index_, data); } SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) @@ -270,7 +273,8 @@ ObjectPtr SwitchableCallPattern::target() const { void SwitchableCallPattern::SetTarget(const Code& target) const { ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); - object_pool_.SetObjectAt(target_pool_index_, target); + object_pool_.SetObjectAt(target_pool_index_, + target); } BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc) @@ -296,8 +300,8 @@ uword BareSwitchableCallPattern::target_entry() const { void BareSwitchableCallPattern::SetTarget(const Code& target) const { ASSERT(object_pool_.TypeAt(target_pool_index_) == ObjectPool::EntryType::kImmediate); - object_pool_.SetRawValueAt(target_pool_index_, - target.MonomorphicEntryPoint()); + object_pool_.SetRawValueAt( + target_pool_index_, target.MonomorphicEntryPoint()); } ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {} diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc index ce5d1221ef3..c0f5db4d38b 100644 --- a/runtime/vm/instructions_arm64.cc +++ b/runtime/vm/instructions_arm64.cc @@ -76,7 +76,8 @@ CodePtr NativeCallPattern::target() const { } void NativeCallPattern::set_target(const Code& target) const { - object_pool_.SetObjectAt(target_code_pool_index_, target); + object_pool_.SetObjectAt(target_code_pool_index_, + target); // No need to flush the instruction cache, since the code is not modified. } @@ -86,8 +87,8 @@ NativeFunction NativeCallPattern::native_function() const { } void NativeCallPattern::set_native_function(NativeFunction func) const { - object_pool_.SetRawValueAt(native_function_pool_index_, - reinterpret_cast(func)); + object_pool_.SetRawValueAt( + native_function_pool_index_, reinterpret_cast(func)); } // Decodes a load sequence ending at 'end' (the last instruction of the load @@ -398,7 +399,8 @@ CodePtr CallPattern::TargetCode() const { } void CallPattern::SetTargetCode(const Code& target) const { - object_pool_.SetObjectAt(target_code_pool_index_, target); + object_pool_.SetObjectAt(target_code_pool_index_, + target); // No need to flush the instruction cache, since the code is not modified. } @@ -408,7 +410,7 @@ ObjectPtr ICCallPattern::Data() const { void ICCallPattern::SetData(const Object& data) const { ASSERT(data.IsArray() || data.IsICData() || data.IsMegamorphicCache()); - object_pool_.SetObjectAt(data_pool_index_, data); + object_pool_.SetObjectAt(data_pool_index_, data); } CodePtr ICCallPattern::TargetCode() const { @@ -416,7 +418,8 @@ CodePtr ICCallPattern::TargetCode() const { } void ICCallPattern::SetTargetCode(const Code& target) const { - object_pool_.SetObjectAt(target_pool_index_, target); + object_pool_.SetObjectAt(target_pool_index_, + target); // No need to flush the instruction cache, since the code is not modified. } @@ -430,7 +433,7 @@ ObjectPtr SwitchableCallPatternBase::data() const { void SwitchableCallPatternBase::SetData(const Object& data) const { ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); - object_pool_.SetObjectAt(data_pool_index_, data); + object_pool_.SetObjectAt(data_pool_index_, data); } SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) @@ -456,7 +459,8 @@ ObjectPtr SwitchableCallPattern::target() const { void SwitchableCallPattern::SetTarget(const Code& target) const { ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); - object_pool_.SetObjectAt(target_pool_index_, target); + object_pool_.SetObjectAt(target_pool_index_, + target); } BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc) @@ -483,8 +487,8 @@ uword BareSwitchableCallPattern::target_entry() const { void BareSwitchableCallPattern::SetTarget(const Code& target) const { ASSERT(object_pool_.TypeAt(target_pool_index_) == ObjectPool::EntryType::kImmediate); - object_pool_.SetRawValueAt(target_pool_index_, - target.MonomorphicEntryPoint()); + object_pool_.SetRawValueAt( + target_pool_index_, target.MonomorphicEntryPoint()); } ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {} diff --git a/runtime/vm/instructions_riscv.cc b/runtime/vm/instructions_riscv.cc index 1809cb7aaab..ee81f345beb 100644 --- a/runtime/vm/instructions_riscv.cc +++ b/runtime/vm/instructions_riscv.cc @@ -90,7 +90,8 @@ CodePtr NativeCallPattern::target() const { } void NativeCallPattern::set_target(const Code& target) const { - object_pool_.SetObjectAt(target_code_pool_index_, target); + object_pool_.SetObjectAt(target_code_pool_index_, + target); // No need to flush the instruction cache, since the code is not modified. } @@ -100,8 +101,8 @@ NativeFunction NativeCallPattern::native_function() const { } void NativeCallPattern::set_native_function(NativeFunction func) const { - object_pool_.SetRawValueAt(native_function_pool_index_, - reinterpret_cast(func)); + object_pool_.SetRawValueAt( + native_function_pool_index_, reinterpret_cast(func)); } // Decodes a load sequence ending at 'end' (the last instruction of the load @@ -297,7 +298,8 @@ CodePtr CallPattern::TargetCode() const { } void CallPattern::SetTargetCode(const Code& target) const { - object_pool_.SetObjectAt(target_code_pool_index_, target); + object_pool_.SetObjectAt(target_code_pool_index_, + target); // No need to flush the instruction cache, since the code is not modified. } @@ -307,7 +309,7 @@ ObjectPtr ICCallPattern::Data() const { void ICCallPattern::SetData(const Object& data) const { ASSERT(data.IsArray() || data.IsICData() || data.IsMegamorphicCache()); - object_pool_.SetObjectAt(data_pool_index_, data); + object_pool_.SetObjectAt(data_pool_index_, data); } CodePtr ICCallPattern::TargetCode() const { @@ -315,7 +317,8 @@ CodePtr ICCallPattern::TargetCode() const { } void ICCallPattern::SetTargetCode(const Code& target) const { - object_pool_.SetObjectAt(target_pool_index_, target); + object_pool_.SetObjectAt(target_pool_index_, + target); // No need to flush the instruction cache, since the code is not modified. } @@ -359,7 +362,8 @@ ObjectPtr SwitchableCallPattern::target() const { void SwitchableCallPattern::SetTarget(const Code& target) const { ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); - object_pool_.SetObjectAt(target_pool_index_, target); + object_pool_.SetObjectAt(target_pool_index_, + target); } BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc) @@ -389,8 +393,8 @@ uword BareSwitchableCallPattern::target_entry() const { void BareSwitchableCallPattern::SetTarget(const Code& target) const { ASSERT(object_pool_.TypeAt(target_pool_index_) == ObjectPool::EntryType::kImmediate); - object_pool_.SetRawValueAt(target_pool_index_, - target.MonomorphicEntryPoint()); + object_pool_.SetRawValueAt( + target_pool_index_, target.MonomorphicEntryPoint()); } ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {} diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 5f9be7480b7..55449c509cc 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -8396,8 +8396,6 @@ void Function::SetInstructionsSafe(const Code& value) const { void Function::AttachCode(const Code& value) const { ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter()); - // Finish setting up code before activating it. - value.set_owner(*this); SetInstructions(value); ASSERT(Function::Handle(value.function()).IsNull() || (value.function() == this->ptr())); @@ -12275,7 +12273,7 @@ const char* FunctionType::ToCString() const { } void ClosureData::set_context_scope(const ContextScope& value) const { - untag()->set_context_scope(value.ptr()); + untag()->set_context_scope(value.ptr()); } void ClosureData::set_implicit_static_closure(const Closure& closure) const { @@ -12824,7 +12822,8 @@ void Field::set_dependent_code(const WeakArray& array) const { ASSERT(IsOriginal()); DEBUG_ASSERT( IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter()); - untag()->set_dependent_code(array.ptr()); + // relaxed: races with Field::Clone. + untag()->set_dependent_code(array.ptr()); } class FieldDependentArray : public WeakCodeReferences { diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 5c1182211a8..7aa7c20ac17 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -828,18 +828,28 @@ class Object { // methods below or their counterparts in UntaggedObject, to ensure that the // write barrier is correctly applied. - template + template + type LoadPointer(type const* addr) const { + return ptr()->untag()->LoadPointer(addr); + } + template type LoadPointer(type const* addr) const { return ptr()->untag()->LoadPointer(addr); } - template + template + void StorePointer(type const* addr, type value) const { + ptr()->untag()->StorePointer(addr, value); + } + template void StorePointer(type const* addr, type value) const { ptr()->untag()->StorePointer(addr, value); } - template + template + void StoreCompressedPointer(compressed_type const* addr, type value) const { + ptr()->untag()->StoreCompressedPointer(addr, value); + } + template void StoreCompressedPointer(compressed_type const* addr, type value) const { ptr()->untag()->StoreCompressedPointer(addr, value); @@ -4386,7 +4396,9 @@ class ClosureData : public Object { UntaggedClosureData::kNoAwaiterLinkDepth; private: - ContextScopePtr context_scope() const { return untag()->context_scope(); } + ContextScopePtr context_scope() const { + return untag()->context_scope(); + } void set_context_scope(const ContextScope& value) const; void set_packed_fields(uint32_t value) const { @@ -5695,13 +5707,22 @@ class ObjectPool : public Object { StoreNonPointer(&untag()->entry_bits()[index], bits); } - template + ObjectPtr ObjectAt(intptr_t index) const { + ASSERT(TypeAt(index) == EntryType::kTaggedObject); + return LoadPointer(&(EntryAddr(index)->raw_obj_)); + } + template ObjectPtr ObjectAt(intptr_t index) const { ASSERT(TypeAt(index) == EntryType::kTaggedObject); return LoadPointer(&(EntryAddr(index)->raw_obj_)); } - template + void SetObjectAt(intptr_t index, const Object& obj) const { + ASSERT((TypeAt(index) == EntryType::kTaggedObject) || + (TypeAt(index) == EntryType::kImmediate && obj.IsSmi())); + StorePointer(&EntryAddr(index)->raw_obj_, obj.ptr()); + } + template void SetObjectAt(intptr_t index, const Object& obj) const { ASSERT((TypeAt(index) == EntryType::kTaggedObject) || (TypeAt(index) == EntryType::kImmediate && obj.IsSmi())); @@ -5716,6 +5737,12 @@ class ObjectPool : public Object { ASSERT(TypeAt(index) != EntryType::kTaggedObject); StoreNonPointer(&EntryAddr(index)->raw_value_, raw_value); } + template + void SetRawValueAt(intptr_t index, uword raw_value) const { + ASSERT(TypeAt(index) != EntryType::kTaggedObject); + StoreNonPointer(&EntryAddr(index)->raw_value_, + raw_value); + } static intptr_t InstanceSize() { ASSERT(sizeof(UntaggedObjectPool) == @@ -9540,7 +9567,9 @@ class AbstractType : public Instance { uword type_test_stub_entry_point() const { return untag()->type_test_stub_entry_point_; } - CodePtr type_test_stub() const { return untag()->type_test_stub(); } + CodePtr type_test_stub() const { + return untag()->type_test_stub(); + } // Sets the TTS to [stub]. // @@ -11079,22 +11108,35 @@ class Array : public Instance { return array->untag()->data(); } - template + static ObjectPtr ElementAt(ArrayPtr array, intptr_t index) { + ASSERT((0 <= index) && (index < LengthOf(array))); + return array->untag()->element(index); + } + template static ObjectPtr ElementAt(ArrayPtr array, intptr_t index) { ASSERT((0 <= index) && (index < LengthOf(array))); return array->untag()->element(index); } - template + ObjectPtr At(intptr_t index) const { return ElementAt(ptr(), index); } + template ObjectPtr At(intptr_t index) const { return ElementAt(ptr(), index); } - template + void SetAt(intptr_t index, const Object& value) const { + ASSERT((0 <= index) && (index < Length())); + untag()->set_element(index, value.ptr()); + } + template void SetAt(intptr_t index, const Object& value) const { ASSERT((0 <= index) && (index < Length())); untag()->set_element(index, value.ptr()); } - template + void SetAt(intptr_t index, const Object& value, Thread* thread) const { + ASSERT((0 <= index) && (index < Length())); + untag()->set_element(index, value.ptr(), thread); + } + template void SetAt(intptr_t index, const Object& value, Thread* thread) const { ASSERT((0 <= index) && (index < Length())); untag()->set_element(index, value.ptr(), thread); @@ -11232,9 +11274,11 @@ class Array : public Instance { untag()->set_length(Smi::New(value)); } - template + template + void StoreArrayPointer(type const* addr, value_type value) const { + ptr()->untag()->StoreArrayPointer(addr, value); + } + template void StoreArrayPointer(type const* addr, value_type value) const { ptr()->untag()->StoreArrayPointer(addr, value); } diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc index 2d0dec1dd80..cdec9773dd3 100644 --- a/runtime/vm/object_test.cc +++ b/runtime/vm/object_test.cc @@ -2664,6 +2664,7 @@ ISOLATE_UNIT_TEST_CASE(Code) { thread->isolate_group()->program_lock()); Code& code = Code::Handle(Code::FinalizeCodeAndNotify( function, nullptr, &_assembler_, Code::PoolAttachment::kAttachPool)); + code.set_owner(function); function.AttachCode(code); const Instructions& instructions = Instructions::Handle(code.instructions()); uword payload_start = instructions.PayloadStart(); @@ -2728,6 +2729,7 @@ ISOLATE_UNIT_TEST_CASE(EmbedStringInCode) { thread->isolate_group()->program_lock()); const Code& code = Code::Handle(Code::FinalizeCodeAndNotify( function, nullptr, &_assembler_, Code::PoolAttachment::kAttachPool)); + code.set_owner(function); function.AttachCode(code); const Object& result = Object::Handle(DartEntry::InvokeFunction(function, Array::empty_array())); @@ -2754,6 +2756,7 @@ ISOLATE_UNIT_TEST_CASE(EmbedSmiInCode) { thread->isolate_group()->program_lock()); const Code& code = Code::Handle(Code::FinalizeCodeAndNotify( function, nullptr, &_assembler_, Code::PoolAttachment::kAttachPool)); + code.set_owner(function); function.AttachCode(code); const Object& result = Object::Handle(DartEntry::InvokeFunction(function, Array::empty_array())); @@ -2775,6 +2778,7 @@ ISOLATE_UNIT_TEST_CASE(EmbedSmiIn64BitCode) { thread->isolate_group()->program_lock()); const Code& code = Code::Handle(Code::FinalizeCodeAndNotify( function, nullptr, &_assembler_, Code::PoolAttachment::kAttachPool)); + code.set_owner(function); function.AttachCode(code); const Object& result = Object::Handle(DartEntry::InvokeFunction(function, Array::empty_array())); diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index c4592774d18..cb3cffb861d 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc @@ -558,7 +558,10 @@ VARIABLE_COMPRESSED_VISITOR(TypeArguments, VARIABLE_COMPRESSED_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_) VARIABLE_COMPRESSED_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries()) VARIABLE_COMPRESSED_VISITOR(Context, raw_obj->untag()->num_variables_) -VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag()->length())) +// relaxed: for Array truncation +VARIABLE_COMPRESSED_VISITOR( + Array, + Smi::Value(raw_obj->untag()->length())) VARIABLE_COMPRESSED_VISITOR( TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassIdOfHeapObject()) * diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index cf7f3acc754..5ac177167cb 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -570,14 +570,21 @@ class UntaggedObject { // All writes to heap objects should ultimately pass through one of the // methods below or their counterparts in Object, to ensure that the // write barrier is correctly applied. - template + template + type LoadPointer(type const* addr) const { + return *const_cast(addr); + } + template type LoadPointer(type const* addr) const { return reinterpret_cast*>(const_cast(addr)) ->load(order); } - template + template + type LoadCompressedPointer(compressed_type const* addr) const { + compressed_type v = *const_cast(addr); + return static_cast(v.Decompress(heap_base())); + } + template type LoadCompressedPointer(compressed_type const* addr) const { compressed_type v = reinterpret_cast*>( const_cast(addr)) @@ -596,7 +603,14 @@ class UntaggedObject { return reinterpret_cast(this) & kHeapBaseMask; } - template + template + void StorePointer(type const* addr, type value) { + *const_cast(addr) = value; + if (value.IsHeapObject()) { + CheckHeapPointerStore(value, Thread::Current()); + } + } + template void StorePointer(type const* addr, type value) { reinterpret_cast*>(const_cast(addr)) ->store(value, order); @@ -605,9 +619,14 @@ class UntaggedObject { } } - template + template + void StoreCompressedPointer(compressed_type const* addr, type value) { + *const_cast(addr) = value; + if (value.IsHeapObject()) { + CheckHeapPointerStore(value, Thread::Current()); + } + } + template void StoreCompressedPointer(compressed_type const* addr, type value) { reinterpret_cast*>( const_cast(addr)) @@ -644,9 +663,14 @@ class UntaggedObject { } // Note: StoreArrayPointer won't work if value_type is a compressed pointer. - template + template + void StoreArrayPointer(type const* addr, value_type value) { + *const_cast(addr) = type(value); + if (value->IsHeapObject()) { + CheckArrayPointerStore(addr, value, Thread::Current()); + } + } + template void StoreArrayPointer(type const* addr, value_type value) { reinterpret_cast*>(const_cast(addr)) ->store(type(value), order); @@ -663,6 +687,13 @@ class UntaggedObject { } } + template + void StoreCompressedArrayPointer(compressed_type const* addr, type value) { + *const_cast(addr) = static_cast(value); + if (value->IsHeapObject()) { + CheckArrayPointerStore(addr, value, Thread::Current()); + } + } template void StoreCompressedArrayPointer(compressed_type const* addr, type value) { reinterpret_cast*>( @@ -709,12 +740,19 @@ class UntaggedObject { return static_cast(previous_value.Decompress(heap_base())); } - template + SmiPtr LoadSmi(SmiPtr const* addr) const { + return *const_cast(addr); + } + template SmiPtr LoadSmi(SmiPtr const* addr) const { return reinterpret_cast*>(const_cast(addr)) ->load(order); } - template + SmiPtr LoadCompressedSmi(CompressedSmiPtr const* addr) const { + return static_cast( + const_cast(addr)->DecompressSmi()); + } + template SmiPtr LoadCompressedSmi(CompressedSmiPtr const* addr) const { return static_cast(reinterpret_cast*>( const_cast(addr)) @@ -724,17 +762,20 @@ class UntaggedObject { // Use for storing into an explicitly Smi-typed field of an object // (i.e., both the previous and new value are Smis). - template + template + void StoreSmi(type const* addr, type value) { + *const_cast(addr) = value; + } + template void StoreSmi(type const* addr, type value) { - // Can't use Contains, as array length is initialized through this method. - ASSERT(reinterpret_cast(addr) >= UntaggedObject::ToAddr(this)); reinterpret_cast*>(const_cast(addr)) ->store(value, order); } - template void StoreCompressedSmi(CompressedSmiPtr const* addr, SmiPtr value) { - // Can't use Contains, as array length is initialized through this method. - ASSERT(reinterpret_cast(addr) >= UntaggedObject::ToAddr(this)); + *const_cast(addr) = value; + } + template + void StoreCompressedSmi(CompressedSmiPtr const* addr, SmiPtr value) { reinterpret_cast*>( const_cast(addr)) ->store(static_cast(value), order); @@ -896,11 +937,17 @@ inline intptr_t ObjectPtr::GetClassId() const { #define POINTER_FIELD(type, name) \ public: \ - template \ + type name() const { \ + return LoadPointer(&name##_); \ + } \ + template \ type name() const { \ return LoadPointer(&name##_); \ } \ - template \ + void set_##name(type value) { \ + StorePointer(&name##_, value); \ + } \ + template \ void set_##name(type value) { \ StorePointer(&name##_, value); \ } \ @@ -910,14 +957,20 @@ inline intptr_t ObjectPtr::GetClassId() const { #define COMPRESSED_POINTER_FIELD(type, name) \ public: \ - template \ + type name() const { \ + return LoadCompressedPointer(&name##_); \ + } \ + template \ type name() const { \ return LoadCompressedPointer(&name##_); \ } \ type name##_ignore_race() const { \ return LoadCompressedPointerIgnoreRace(&name##_); \ } \ - template \ + void set_##name(type value) { \ + StoreCompressedPointer(&name##_, value); \ + } \ + template \ void set_##name(type value) { \ StoreCompressedPointer(&name##_, value); \ } \ @@ -927,11 +980,17 @@ inline intptr_t ObjectPtr::GetClassId() const { #define ARRAY_POINTER_FIELD(type, name) \ public: \ - template \ + type name() const { \ + return LoadPointer(&name##_); \ + } \ + template \ type name() const { \ return LoadPointer(&name##_); \ } \ - template \ + void set_##name(type value) { \ + StoreArrayPointer(&name##_, value); \ + } \ + template \ void set_##name(type value) { \ StoreArrayPointer(&name##_, value); \ } \ @@ -941,12 +1000,18 @@ inline intptr_t ObjectPtr::GetClassId() const { #define COMPRESSED_ARRAY_POINTER_FIELD(type, name) \ public: \ - template \ + type name() const { \ + return LoadPointer(&name##_).Decompress(heap_base()); \ + } \ + template \ type name() const { \ return LoadPointer(&name##_).Decompress( \ heap_base()); \ } \ - template \ + void set_##name(type value) { \ + StoreCompressedArrayPointer(&name##_, value); \ + } \ + template \ void set_##name(type value) { \ StoreCompressedArrayPointer(&name##_, \ value); \ @@ -957,15 +1022,24 @@ inline intptr_t ObjectPtr::GetClassId() const { #define VARIABLE_POINTER_FIELDS(type, accessor_name, array_name) \ public: \ - template \ + type accessor_name(intptr_t index) const { \ + return LoadPointer(&array_name()[index]); \ + } \ + template \ type accessor_name(intptr_t index) const { \ return LoadPointer(&array_name()[index]); \ } \ - template \ + void set_##accessor_name(intptr_t index, type value) { \ + StoreArrayPointer(&array_name()[index], value); \ + } \ + template \ void set_##accessor_name(intptr_t index, type value) { \ StoreArrayPointer(&array_name()[index], value); \ } \ - template \ + void set_##accessor_name(intptr_t index, type value, Thread* thread) { \ + StoreArrayPointer(&array_name()[index], value, thread); \ + } \ + template \ void set_##accessor_name(intptr_t index, type value, Thread* thread) { \ StoreArrayPointer(&array_name()[index], value, thread); \ } \ @@ -981,17 +1055,29 @@ inline intptr_t ObjectPtr::GetClassId() const { #define COMPRESSED_VARIABLE_POINTER_FIELDS(type, accessor_name, array_name) \ public: \ - template \ + type accessor_name(intptr_t index) const { \ + return LoadCompressedPointer( \ + &array_name()[index]); \ + } \ + template \ type accessor_name(intptr_t index) const { \ return LoadCompressedPointer( \ &array_name()[index]); \ } \ - template \ + void set_##accessor_name(intptr_t index, type value) { \ + StoreCompressedArrayPointer(&array_name()[index], \ + value); \ + } \ + template \ void set_##accessor_name(intptr_t index, type value) { \ StoreCompressedArrayPointer( \ &array_name()[index], value); \ } \ - template \ + void set_##accessor_name(intptr_t index, type value, Thread* thread) { \ + StoreCompressedArrayPointer(&array_name()[index], \ + value, thread); \ + } \ + template \ void set_##accessor_name(intptr_t index, type value, Thread* thread) { \ StoreCompressedArrayPointer( \ &array_name()[index], value, thread); \ @@ -1008,13 +1094,22 @@ inline intptr_t ObjectPtr::GetClassId() const { #define SMI_FIELD(type, name) \ public: \ - template \ + type name() const { \ + type result = LoadSmi(&name##_); \ + ASSERT(!result.IsHeapObject()); \ + return result; \ + } \ + template \ type name() const { \ type result = LoadSmi(&name##_); \ ASSERT(!result.IsHeapObject()); \ return result; \ } \ - template \ + void set_##name(type value) { \ + ASSERT(!value.IsHeapObject()); \ + StoreSmi(&name##_, value); \ + } \ + template \ void set_##name(type value) { \ ASSERT(!value.IsHeapObject()); \ StoreSmi(&name##_, value); \ @@ -1025,16 +1120,25 @@ inline intptr_t ObjectPtr::GetClassId() const { #define COMPRESSED_SMI_FIELD(type, name) \ public: \ - template \ + type name() const { \ + type result = LoadCompressedSmi(&name##_); \ + ASSERT(!result.IsHeapObject()); \ + return result; \ + } \ + template \ type name() const { \ type result = LoadCompressedSmi(&name##_); \ ASSERT(!result.IsHeapObject()); \ return result; \ } \ - template \ void set_##name(type value) { \ ASSERT(!value.IsHeapObject()); \ StoreCompressedSmi(&name##_, value); \ + } \ + template \ + void set_##name(type value) { \ + ASSERT(!value.IsHeapObject()); \ + StoreCompressedSmi(&name##_, value); \ } \ \ protected: \ @@ -2403,9 +2507,6 @@ class UntaggedLocalVarDescriptors : public UntaggedObject { COMPRESSED_VARIABLE_POINTER_FIELDS(StringPtr, name, names) CompressedStringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); } - void set_name(intptr_t i, StringPtr value) { - StoreCompressedPointer(nameAddrAt(i), value); - } // Variable info with [num_entries_] entries. VarInfo* data() { diff --git a/runtime/vm/stub_code_test.cc b/runtime/vm/stub_code_test.cc index 25d1d465cef..6523050f383 100644 --- a/runtime/vm/stub_code_test.cc +++ b/runtime/vm/stub_code_test.cc @@ -29,6 +29,7 @@ const Function& RegisterFakeFunction(const char* name, const Code& code) { owner_class.SetFunctions(functions); } lib.AddClass(owner_class); + code.set_owner(function); function.AttachCode(code); return function; }