Fix dangling SingleImplementations left after class unloading

Test: make test-art-host, manual using sample code

bug: 73143991

Change-Id: I4d56b39c69d4ed60266a8b90b9e9d18fba7b8227
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 579e554..bd9b64d 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -172,8 +172,9 @@
     return (GetAccessFlags() & synchonized) != 0;
   }
 
+  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsFinal() {
-    return (GetAccessFlags() & kAccFinal) != 0;
+    return (GetAccessFlags<kReadBarrierOption>() & kAccFinal) != 0;
   }
 
   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
@@ -242,10 +243,11 @@
   }
 
   // This is set by the class linker.
+  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsDefault() {
     static_assert((kAccDefault & (kAccIntrinsic | kAccIntrinsicBits)) == 0,
                   "kAccDefault conflicts with intrinsic modifier");
-    return (GetAccessFlags() & kAccDefault) != 0;
+    return (GetAccessFlags<kReadBarrierOption>() & kAccDefault) != 0;
   }
 
   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
@@ -280,8 +282,9 @@
     return (GetAccessFlags() & mask) == mask;
   }
 
+  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsAbstract() {
-    return (GetAccessFlags() & kAccAbstract) != 0;
+    return (GetAccessFlags<kReadBarrierOption>() & kAccAbstract) != 0;
   }
 
   bool IsSynthetic() {
@@ -496,6 +499,7 @@
     return DataOffset(kRuntimePointerSize);
   }
 
+  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   ALWAYS_INLINE bool HasSingleImplementation() REQUIRES_SHARED(Locks::mutator_lock_);
 
   ALWAYS_INLINE void SetHasSingleImplementation(bool single_impl) {
@@ -513,12 +517,15 @@
   ArtMethod* GetCanonicalMethod(PointerSize pointer_size = kRuntimePointerSize)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   ArtMethod* GetSingleImplementation(PointerSize pointer_size)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   ALWAYS_INLINE void SetSingleImplementation(ArtMethod* method, PointerSize pointer_size) {
-    DCHECK(!IsNative());
-    DCHECK(IsAbstract());  // Non-abstract method's single implementation is just itself.
+    DCHECK(!IsNative<kReadBarrierOption>());
+    // Non-abstract method's single implementation is just itself.
+    DCHECK(IsAbstract<kReadBarrierOption>());
     SetDataPtrSize(method, pointer_size);
   }