diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h index d5a010e178a..2132fd482ad 100644 --- a/runtime/vm/code_patcher.h +++ b/runtime/vm/code_patcher.h @@ -79,8 +79,6 @@ class CodePatcher : public AllStatic { const Code& target); static ObjectPtr GetSwitchableCallDataAt(uword return_address, const Code& caller_code); - static ObjectPtr GetSwitchableCallTargetAt(uword return_address, - const Code& caller_code); static uword GetSwitchableCallTargetEntryAt(uword return_address, const Code& caller_code); diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc index 421adcfe6cd..179936fcef8 100644 --- a/runtime/vm/code_patcher_arm.cc +++ b/runtime/vm/code_patcher_arm.cc @@ -86,9 +86,12 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, const Code& caller_code, const Object& data, const Code& target) { + // We lock to block other writers but don't start a safepoint to block readers + // (i.e., Dart execution). // First update target to a stub that does not read 'data' so that concurrent // Dart execution cannot observe the new stub with the old data or the old // stub with the new data. + SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex()); if (FLAG_precompiled_mode) { BareSwitchableCallPattern call(return_address); call.SetTargetRelease(StubCode::SwitchableCallMiss()); @@ -102,16 +105,6 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, } } -ObjectPtr CodePatcher::GetSwitchableCallTargetAt(uword return_address, - const Code& caller_code) { - if (FLAG_precompiled_mode) { - UNREACHABLE(); - } else { - SwitchableCallPattern call(return_address, caller_code); - return call.target(); - } -} - uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address, const Code& caller_code) { if (FLAG_precompiled_mode) { diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc index 9740f0f75f2..e44c6785ed6 100644 --- a/runtime/vm/code_patcher_arm64.cc +++ b/runtime/vm/code_patcher_arm64.cc @@ -114,9 +114,12 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, const Code& caller_code, const Object& data, const Code& target) { + // We lock to block other writers but don't start a safepoint to block readers + // (i.e., Dart execution). // First update target to a stub that does not read 'data' so that concurrent // Dart execution cannot observe the new stub with the old data or the old // stub with the new data. + SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex()); if (FLAG_precompiled_mode) { BareSwitchableCallPattern call(return_address); call.SetTargetRelease(StubCode::SwitchableCallMiss()); @@ -130,16 +133,6 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, } } -ObjectPtr CodePatcher::GetSwitchableCallTargetAt(uword return_address, - const Code& caller_code) { - if (FLAG_precompiled_mode) { - UNREACHABLE(); - } else { - SwitchableCallPattern call(return_address, caller_code); - return call.target(); - } -} - uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address, const Code& caller_code) { if (FLAG_precompiled_mode) { diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc index 0c1e28a5f27..8a195d06ce2 100644 --- a/runtime/vm/code_patcher_ia32.cc +++ b/runtime/vm/code_patcher_ia32.cc @@ -257,12 +257,6 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, PatchInstanceCallAt(return_address, caller_code, data, target); } -ObjectPtr CodePatcher::GetSwitchableCallTargetAt(uword return_address, - const Code& caller_code) { - InstanceCall call(return_address, caller_code); - return call.target(); -} - uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address, const Code& caller_code) { // Switchable instance calls only generated for precompilation. diff --git a/runtime/vm/code_patcher_riscv.cc b/runtime/vm/code_patcher_riscv.cc index f5f95b6ac13..035ba31c54c 100644 --- a/runtime/vm/code_patcher_riscv.cc +++ b/runtime/vm/code_patcher_riscv.cc @@ -123,9 +123,12 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, const Code& caller_code, const Object& data, const Code& target) { + // We lock to block other writers but don't start a safepoint to block readers + // (i.e., Dart execution). // First update target to a stub that does not read 'data' so that concurrent // Dart execution cannot observe the new stub with the old data or the old // stub with the new data. + SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex()); if (FLAG_precompiled_mode) { BareSwitchableCallPattern call(return_address); call.SetTargetRelease(StubCode::SwitchableCallMiss()); @@ -139,16 +142,6 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, } } -ObjectPtr CodePatcher::GetSwitchableCallTargetAt(uword return_address, - const Code& caller_code) { - if (FLAG_precompiled_mode) { - UNREACHABLE(); - } else { - SwitchableCallPattern call(return_address, caller_code); - return call.target(); - } -} - uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address, const Code& caller_code) { if (FLAG_precompiled_mode) { diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc index f60a0062dc3..2d6cf0586a1 100644 --- a/runtime/vm/code_patcher_x64.cc +++ b/runtime/vm/code_patcher_x64.cc @@ -294,7 +294,9 @@ class SwitchableCallBase : public ValueObject { intptr_t data_index() const { return data_index_; } intptr_t target_index() const { return target_index_; } - ObjectPtr data() const { return object_pool_.ObjectAt(data_index()); } + ObjectPtr data() const { + return object_pool_.ObjectAt(data_index()); + } void SetDataRelease(const Object& data) const { ASSERT(!Object::Handle(object_pool_.ObjectAt(data_index())).IsCode()); @@ -442,7 +444,9 @@ class BareSwitchableCall : public SwitchableCallBase { target_index(), target.MonomorphicEntryPoint()); } - uword target_entry() const { return object_pool_.RawValueAt(target_index()); } + uword target_entry() const { + return object_pool_.RawValueAt(target_index()); + } }; CodePtr CodePatcher::GetStaticCallTargetAt(uword return_address, @@ -518,9 +522,12 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, const Code& caller_code, const Object& data, const Code& target) { + // We lock to block other writers but don't start a safepoint to block readers + // (i.e., Dart execution). // First update target to a stub that does not read 'data' so that concurrent // Dart execution cannot observe the new stub with the old data or the old // stub with the new data. + SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex()); if (FLAG_precompiled_mode) { BareSwitchableCall call(return_address); call.SetTargetRelease(StubCode::SwitchableCallMiss()); @@ -534,16 +541,6 @@ void CodePatcher::PatchSwitchableCallAt(uword return_address, } } -ObjectPtr CodePatcher::GetSwitchableCallTargetAt(uword return_address, - const Code& caller_code) { - if (FLAG_precompiled_mode) { - UNREACHABLE(); - } else { - SwitchableCall call(return_address, caller_code); - return call.target(); - } -} - uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address, const Code& caller_code) { if (FLAG_precompiled_mode) { diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc index de009e207dc..5a5a67e6b5c 100644 --- a/runtime/vm/instructions_arm.cc +++ b/runtime/vm/instructions_arm.cc @@ -244,7 +244,7 @@ SwitchableCallPatternBase::SwitchableCallPatternBase( : object_pool_(object_pool), data_pool_index_(-1), target_pool_index_(-1) {} ObjectPtr SwitchableCallPatternBase::data() const { - return object_pool_.ObjectAt(data_pool_index_); + return object_pool_.ObjectAt(data_pool_index_); } void SwitchableCallPatternBase::SetDataRelease(const Object& data) const { @@ -294,7 +294,7 @@ BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc) } uword BareSwitchableCallPattern::target_entry() const { - return object_pool_.RawValueAt(target_pool_index_); + return object_pool_.RawValueAt(target_pool_index_); } void BareSwitchableCallPattern::SetTargetRelease(const Code& target) const { diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc index c18dc714cbe..4802eaa4313 100644 --- a/runtime/vm/instructions_arm64.cc +++ b/runtime/vm/instructions_arm64.cc @@ -428,7 +428,7 @@ SwitchableCallPatternBase::SwitchableCallPatternBase( : object_pool_(object_pool), data_pool_index_(-1), target_pool_index_(-1) {} ObjectPtr SwitchableCallPatternBase::data() const { - return object_pool_.ObjectAt(data_pool_index_); + return object_pool_.ObjectAt(data_pool_index_); } void SwitchableCallPatternBase::SetDataRelease(const Object& data) const { @@ -481,7 +481,7 @@ BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc) } uword BareSwitchableCallPattern::target_entry() const { - return object_pool_.RawValueAt(target_pool_index_); + return object_pool_.RawValueAt(target_pool_index_); } void BareSwitchableCallPattern::SetTargetRelease(const Code& target) const { diff --git a/runtime/vm/instructions_riscv.cc b/runtime/vm/instructions_riscv.cc index 7a97ce5ec11..f7d249096ed 100644 --- a/runtime/vm/instructions_riscv.cc +++ b/runtime/vm/instructions_riscv.cc @@ -327,7 +327,7 @@ SwitchableCallPatternBase::SwitchableCallPatternBase( : object_pool_(object_pool), data_pool_index_(-1), target_pool_index_(-1) {} ObjectPtr SwitchableCallPatternBase::data() const { - return object_pool_.ObjectAt(data_pool_index_); + return object_pool_.ObjectAt(data_pool_index_); } void SwitchableCallPatternBase::SetDataRelease(const Object& data) const { @@ -387,7 +387,7 @@ BareSwitchableCallPattern::BareSwitchableCallPattern(uword pc) } uword BareSwitchableCallPattern::target_entry() const { - return object_pool_.RawValueAt(target_pool_index_); + return object_pool_.RawValueAt(target_pool_index_); } void BareSwitchableCallPattern::SetTargetRelease(const Code& target) const { diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 5c32b477b11..f7a5470bc7f 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -5745,7 +5745,12 @@ class ObjectPool : public Object { uword RawValueAt(intptr_t index) const { ASSERT(TypeAt(index) != EntryType::kTaggedObject); - return EntryAddr(index)->raw_value_; + return LoadNonPointer(&EntryAddr(index)->raw_value_); + } + template + uword RawValueAt(intptr_t index) const { + ASSERT(TypeAt(index) != EntryType::kTaggedObject); + return LoadNonPointer(&EntryAddr(index)->raw_value_); } void SetRawValueAt(intptr_t index, uword raw_value) const { ASSERT(TypeAt(index) != EntryType::kTaggedObject);