diff options
author | 2023-03-03 15:27:22 +0000 | |
---|---|---|
committer | 2023-03-04 10:51:17 +0000 | |
commit | 8c0fcaad777a4b941426c98859f392780adeb0cb (patch) | |
tree | 7c920e07d493a996a5613d6b73cdf139b3b5a62c | |
parent | cbeab409e1a2067a734214abaf55a599a8c330f5 (diff) |
Make entries in dex cache arrays atomic.
They are read / written concurrently, so tell it to the compiler.
Test: m
Change-Id: Iaf3e45100ac57d50a17098d8efacf53597a2882a
-rw-r--r-- | runtime/gc/space/image_space.cc | 2 | ||||
-rw-r--r-- | runtime/mirror/dex_cache-inl.h | 26 | ||||
-rw-r--r-- | runtime/mirror/dex_cache.h | 19 |
3 files changed, 25 insertions, 22 deletions
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 2e8f6be641..c2002232b2 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -398,7 +398,7 @@ class ImageSpace::PatchObjectVisitor final { } uint32_t size = reinterpret_cast<uint32_t*>(array)[-1]; for (uint32_t i = 0; i < size; ++i) { - PatchGcRoot(&array->GetGcRoot(i)); + PatchGcRoot(array->GetGcRootAddress(i)); } } diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index 3452f17d70..ddfc6b2fa9 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -118,12 +118,12 @@ inline void NativeDexCachePair<T>::Initialize(std::atomic<NativeDexCachePair<T>> template <typename T> inline void GcRootArray<T>::Set(uint32_t index, T* value) { GcRoot<T> root(value); - entries_[index] = root; + entries_[index].store(root, std::memory_order_relaxed); } template <typename T> inline T* GcRootArray<T>::Get(uint32_t index) { - return entries_[index].Read(); + return entries_[index].load(std::memory_order_relaxed).Read(); } inline uint32_t DexCache::ClassSize(PointerSize pointer_size) { @@ -214,10 +214,8 @@ inline CallSite* DexCache::GetResolvedCallSite(uint32_t call_site_idx) { if (UNLIKELY(call_sites == nullptr)) { return nullptr; } - GcRoot<mirror::CallSite>& target = call_sites->GetGcRoot(call_site_idx); - Atomic<GcRoot<mirror::CallSite>>& ref = - reinterpret_cast<Atomic<GcRoot<mirror::CallSite>>&>(target); - return ref.load(std::memory_order_seq_cst).Read(); + Atomic<GcRoot<mirror::CallSite>>* target = call_sites->GetGcRoot(call_site_idx); + return target->load(std::memory_order_seq_cst).Read(); } inline ObjPtr<CallSite> DexCache::SetResolvedCallSite(uint32_t call_site_idx, @@ -231,17 +229,15 @@ inline ObjPtr<CallSite> DexCache::SetResolvedCallSite(uint32_t call_site_idx, if (UNLIKELY(call_sites == nullptr)) { call_sites = AllocateResolvedCallSites(); } - GcRoot<mirror::CallSite>& target = call_sites->GetGcRoot(call_site_idx); + Atomic<GcRoot<mirror::CallSite>>* target = call_sites->GetGcRoot(call_site_idx); // The first assignment for a given call site wins. - Atomic<GcRoot<mirror::CallSite>>& ref = - reinterpret_cast<Atomic<GcRoot<mirror::CallSite>>&>(target); - if (ref.CompareAndSetStrongSequentiallyConsistent(null_call_site, candidate)) { + if (target->CompareAndSetStrongSequentiallyConsistent(null_call_site, candidate)) { // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. WriteBarrier::ForEveryFieldWrite(this); return call_site; } else { - return target.Read(); + return target->load(std::memory_order_relaxed).Read(); } } @@ -323,26 +319,26 @@ inline void DexCache::VisitNativeRoots(const Visitor& visitor) { GcRootArray<mirror::CallSite>* resolved_call_sites = GetResolvedCallSites<kVerifyFlags>(); size_t num_call_sites = NumResolvedCallSites<kVerifyFlags>(); for (size_t i = 0; resolved_call_sites != nullptr && i != num_call_sites; ++i) { - visitor.VisitRootIfNonNull(resolved_call_sites->GetGcRoot(i).AddressWithoutBarrier()); + visitor.VisitRootIfNonNull(resolved_call_sites->GetGcRootAddress(i)->AddressWithoutBarrier()); } GcRootArray<mirror::Class>* resolved_types = GetResolvedTypesArray<kVerifyFlags>(); size_t num_resolved_types = NumResolvedTypesArray<kVerifyFlags>(); for (size_t i = 0; resolved_types != nullptr && i != num_resolved_types; ++i) { - visitor.VisitRootIfNonNull(resolved_types->GetGcRoot(i).AddressWithoutBarrier()); + visitor.VisitRootIfNonNull(resolved_types->GetGcRootAddress(i)->AddressWithoutBarrier()); } GcRootArray<mirror::String>* resolved_strings = GetStringsArray<kVerifyFlags>(); size_t num_resolved_strings = NumStringsArray<kVerifyFlags>(); for (size_t i = 0; resolved_strings != nullptr && i != num_resolved_strings; ++i) { - visitor.VisitRootIfNonNull(resolved_strings->GetGcRoot(i).AddressWithoutBarrier()); + visitor.VisitRootIfNonNull(resolved_strings->GetGcRootAddress(i)->AddressWithoutBarrier()); } GcRootArray<mirror::MethodType>* resolved_method_types = GetResolvedMethodTypesArray<kVerifyFlags>(); size_t num_resolved_method_types = NumResolvedMethodTypesArray<kVerifyFlags>(); for (size_t i = 0; resolved_method_types != nullptr && i != num_resolved_method_types; ++i) { - visitor.VisitRootIfNonNull(resolved_method_types->GetGcRoot(i).AddressWithoutBarrier()); + visitor.VisitRootIfNonNull(resolved_method_types->GetGcRootAddress(i)->AddressWithoutBarrier()); } } diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 856dd1fac2..099fe00656 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -211,14 +211,21 @@ template <typename T> class GcRootArray { T* Get(uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_); - GcRoot<T>& GetGcRoot(uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_) { - return entries_[index]; + Atomic<GcRoot<T>>* GetGcRoot(uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_) { + return &entries_[index]; + } + + // Only to be used in locations that don't need the atomic or will later load + // and read atomically. + GcRoot<T>* GetGcRootAddress(uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_) { + static_assert(sizeof(GcRoot<T>) == sizeof(Atomic<GcRoot<T>>)); + return reinterpret_cast<GcRoot<T>*>(&entries_[index]); } void Set(uint32_t index, T* value) REQUIRES_SHARED(Locks::mutator_lock_); private: - GcRoot<T> entries_[0]; + Atomic<GcRoot<T>> entries_[0]; }; template <typename T> class NativeArray { @@ -226,7 +233,7 @@ template <typename T> class NativeArray { NativeArray() {} T* Get(uint32_t index) { - return entries_[index]; + return entries_[index].load(std::memory_order_relaxed); } T** GetPtrEntryPtrSize(uint32_t index, PointerSize ptr_size) { @@ -240,11 +247,11 @@ template <typename T> class NativeArray { } void Set(uint32_t index, T* value) { - entries_[index] = value; + entries_[index].store(value, std::memory_order_relaxed); } private: - T* entries_[0]; + Atomic<T*> entries_[0]; }; // C++ mirror of java.lang.DexCache. |