summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2023-03-03 15:27:22 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2023-03-04 10:51:17 +0000
commit8c0fcaad777a4b941426c98859f392780adeb0cb (patch)
tree7c920e07d493a996a5613d6b73cdf139b3b5a62c
parentcbeab409e1a2067a734214abaf55a599a8c330f5 (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.cc2
-rw-r--r--runtime/mirror/dex_cache-inl.h26
-rw-r--r--runtime/mirror/dex_cache.h19
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.