OSDN Git Service

Use store release for resolved types
authorMathieu Chartier <mathieuc@google.com>
Wed, 7 Dec 2016 00:02:27 +0000 (16:02 -0800)
committerMathieu Chartier <mathieuc@google.com>
Fri, 9 Dec 2016 23:25:20 +0000 (15:25 -0800)
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

runtime/mirror/dex_cache-inl.h

index be8815a..b54e416 100644 (file)
@@ -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);
 }