summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/mirror/dex_cache-inl.h8
1 files changed, 7 insertions, 1 deletions
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index be8815aba2..b54e416bc0 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -71,6 +71,8 @@ inline void DexCache::ClearString(dex::StringIndex string_idx) {
}
inline Class* DexCache::GetResolvedType(dex::TypeIndex type_idx) {
+ // It is theorized that a load acquire is not required since obtaining the resolved class will
+ // always have an address depedency or a lock.
DCHECK_LT(type_idx.index_, NumResolvedTypes());
return GetResolvedTypes()[type_idx.index_].Read();
}
@@ -78,7 +80,11 @@ inline Class* DexCache::GetResolvedType(dex::TypeIndex type_idx) {
inline void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) {
DCHECK_LT(type_idx.index_, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB.
// TODO default transaction support.
- GetResolvedTypes()[type_idx.index_] = GcRoot<Class>(resolved);
+ // Use a release store for SetResolvedType. This is done to prevent other threads from seeing a
+ // class but not necessarily seeing the loaded members like the static fields array.
+ // See b/32075261.
+ reinterpret_cast<Atomic<GcRoot<mirror::Class>>&>(GetResolvedTypes()[type_idx.index_]).
+ StoreRelease(GcRoot<Class>(resolved));
// TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this);
}