Use store release for resolved types
For DefineClass, 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.
It is theorized that a load acquire is not required since obtaining
the resolved class will always have an address depedency or a lock.
Bug: 32075261
Test: test-art-host
Change-Id: I8ab18edc2cc7c9eb4a30897903d5cf1c7f9eb24e
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index be8815a..b54e416 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -71,6 +71,8 @@
}
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 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);
}