Propagate the read barrier option to Class::VisitNativeRoots.

Propagate the read barrier option from Object::VisitReferences to
Class::VisitNativeRoots.

This is a step toward the GC thread avoiding graying objects (and
reducing dirty pages) in the immune spaces.

Bug: 12687968

Change-Id: I29c4126a4ad4c40e63a934e62451fb3fb36aad43
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 7647ad6..26450c4 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -395,8 +395,9 @@
   return GetDeclaringClass()->GetDexCache();
 }
 
+template<ReadBarrierOption kReadBarrierOption>
 inline bool ArtMethod::IsProxyMethod() {
-  return GetDeclaringClass()->IsProxyClass();
+  return GetDeclaringClass<kReadBarrierOption>()->IsProxyClass();
 }
 
 inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(size_t pointer_size) {
@@ -438,24 +439,24 @@
   return type;
 }
 
-template<typename RootVisitorType>
+template<ReadBarrierOption kReadBarrierOption, typename RootVisitorType>
 void ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) {
-  ArtMethod* interface_method = nullptr;
-  mirror::Class* klass = declaring_class_.Read();
-  if (LIKELY(klass != nullptr)) {
+  if (LIKELY(!declaring_class_.IsNull())) {
+    visitor.VisitRoot(declaring_class_.AddressWithoutBarrier());
+    mirror::Class* klass = declaring_class_.Read<kReadBarrierOption>();
     if (UNLIKELY(klass->IsProxyClass())) {
       // For normal methods, dex cache shortcuts will be visited through the declaring class.
       // However, for proxies we need to keep the interface method alive, so we visit its roots.
-      interface_method = mirror::DexCache::GetElementPtrSize(
+      ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize(
           GetDexCacheResolvedMethods(pointer_size),
           GetDexMethodIndex(),
           pointer_size);
       DCHECK(interface_method != nullptr);
       DCHECK_EQ(interface_method,
-                Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this));
+                Runtime::Current()->GetClassLinker()->FindMethodForProxy<kReadBarrierOption>(
+                    klass, this));
       interface_method->VisitRoots(visitor, pointer_size);
     }
-    visitor.VisitRoot(declaring_class_.AddressWithoutBarrier());
     // We know we don't have profiling information if the class hasn't been verified. Note
     // that this check also ensures the IsNative call can be made, as IsNative expects a fully
     // created class (and not a retired one).
@@ -463,7 +464,7 @@
       // Runtime methods and native methods use the same field as the profiling info for
       // storing their own data (jni entrypoint for native methods, and ImtConflictTable for
       // some runtime methods).
-      if (!IsNative() && !IsRuntimeMethod()) {
+      if (!IsNative<kReadBarrierOption>() && !IsRuntimeMethod()) {
         ProfilingInfo* profiling_info = GetProfilingInfo(pointer_size);
         if (profiling_info != nullptr) {
           profiling_info->VisitRoots(visitor);