Expose VarHandle::AccessModeTemplate and helpers for compiler

Bug: 65872996
Test: art/test/run_test.sh --host 712
Test: art_runtime_tests
Change-Id: I3c19fe8bb1f4be4275c9c0c51ecf8b57ab1b7e96
diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc
index 202134a..7970c62 100644
--- a/runtime/mirror/var_handle.cc
+++ b/runtime/mirror/var_handle.cc
@@ -92,102 +92,9 @@
   { "weakCompareAndSetRelease", VarHandle::AccessMode::kWeakCompareAndSetRelease },
 };
 
-// Enumeration for describing the parameter and return types of an AccessMode.
-enum class AccessModeTemplate : uint32_t {
-  kGet,                 // T Op(C0..CN)
-  kSet,                 // void Op(C0..CN, T)
-  kCompareAndSet,       // boolean Op(C0..CN, T, T)
-  kCompareAndExchange,  // T Op(C0..CN, T, T)
-  kGetAndUpdate,        // T Op(C0..CN, T)
-};
-
-// Look up the AccessModeTemplate for a given VarHandle
-// AccessMode. This simplifies finding the correct signature for a
-// VarHandle accessor method.
-AccessModeTemplate GetAccessModeTemplate(VarHandle::AccessMode access_mode) {
-  switch (access_mode) {
-    case VarHandle::AccessMode::kGet:
-      return AccessModeTemplate::kGet;
-    case VarHandle::AccessMode::kSet:
-      return AccessModeTemplate::kSet;
-    case VarHandle::AccessMode::kGetVolatile:
-      return AccessModeTemplate::kGet;
-    case VarHandle::AccessMode::kSetVolatile:
-      return AccessModeTemplate::kSet;
-    case VarHandle::AccessMode::kGetAcquire:
-      return AccessModeTemplate::kGet;
-    case VarHandle::AccessMode::kSetRelease:
-      return AccessModeTemplate::kSet;
-    case VarHandle::AccessMode::kGetOpaque:
-      return AccessModeTemplate::kGet;
-    case VarHandle::AccessMode::kSetOpaque:
-      return AccessModeTemplate::kSet;
-    case VarHandle::AccessMode::kCompareAndSet:
-      return AccessModeTemplate::kCompareAndSet;
-    case VarHandle::AccessMode::kCompareAndExchange:
-      return AccessModeTemplate::kCompareAndExchange;
-    case VarHandle::AccessMode::kCompareAndExchangeAcquire:
-      return AccessModeTemplate::kCompareAndExchange;
-    case VarHandle::AccessMode::kCompareAndExchangeRelease:
-      return AccessModeTemplate::kCompareAndExchange;
-    case VarHandle::AccessMode::kWeakCompareAndSetPlain:
-      return AccessModeTemplate::kCompareAndSet;
-    case VarHandle::AccessMode::kWeakCompareAndSet:
-      return AccessModeTemplate::kCompareAndSet;
-    case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
-      return AccessModeTemplate::kCompareAndSet;
-    case VarHandle::AccessMode::kWeakCompareAndSetRelease:
-      return AccessModeTemplate::kCompareAndSet;
-    case VarHandle::AccessMode::kGetAndSet:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndSetAcquire:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndSetRelease:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndAdd:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndAddAcquire:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndAddRelease:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseOr:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseOrRelease:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseAnd:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseAndRelease:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseXor:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseXorRelease:
-      return AccessModeTemplate::kGetAndUpdate;
-    case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
-      return AccessModeTemplate::kGetAndUpdate;
-  }
-}
-
-int32_t GetNumberOfVarTypeParameters(AccessModeTemplate access_mode_template) {
-  switch (access_mode_template) {
-    case AccessModeTemplate::kGet:
-      return 0;
-    case AccessModeTemplate::kSet:
-    case AccessModeTemplate::kGetAndUpdate:
-      return 1;
-    case AccessModeTemplate::kCompareAndSet:
-    case AccessModeTemplate::kCompareAndExchange:
-      return 2;
-  }
-  UNREACHABLE();
-}
-
 // Returns the number of parameters associated with an
 // AccessModeTemplate and the supplied coordinate types.
-int32_t GetNumberOfParameters(AccessModeTemplate access_mode_template,
+int32_t GetNumberOfParameters(VarHandle::AccessModeTemplate access_mode_template,
                               ObjPtr<Class> coordinateType0,
                               ObjPtr<Class> coordinateType1) {
   int32_t count = 0;
@@ -197,7 +104,7 @@
       count++;
     }
   }
-  return count + GetNumberOfVarTypeParameters(access_mode_template);
+  return count + VarHandle::GetNumberOfVarTypeParameters(access_mode_template);
 }
 
 void ThrowNullPointerExceptionForCoordinate() REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -225,8 +132,7 @@
 // Returns true if access_mode only entails a memory read. False if
 // access_mode may write to memory.
 bool IsReadOnlyAccessMode(VarHandle::AccessMode access_mode) {
-  AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
-  return access_mode_template == AccessModeTemplate::kGet;
+  return VarHandle::GetAccessModeTemplate(access_mode) == VarHandle::AccessModeTemplate::kGet;
 }
 
 // Writes the parameter types associated with the AccessModeTemplate
@@ -234,7 +140,7 @@
 // variable type and coordinate types. Returns the number of
 // parameters written.
 int32_t BuildParameterArray(ObjPtr<Class> (&parameters)[VarHandle::kMaxAccessorParameters],
-                            AccessModeTemplate access_mode_template,
+                            VarHandle::AccessModeTemplate access_mode_template,
                             ObjPtr<Class> varType,
                             ObjPtr<Class> coordinateType0,
                             ObjPtr<Class> coordinateType1)
@@ -251,34 +157,35 @@
   }
 
   switch (access_mode_template) {
-    case AccessModeTemplate::kCompareAndExchange:
-    case AccessModeTemplate::kCompareAndSet:
+    case VarHandle::AccessModeTemplate::kCompareAndExchange:
+    case VarHandle::AccessModeTemplate::kCompareAndSet:
       parameters[index++] = varType;
       parameters[index++] = varType;
       return index;
-    case AccessModeTemplate::kGet:
+    case VarHandle::AccessModeTemplate::kGet:
       return index;
-    case AccessModeTemplate::kGetAndUpdate:
-    case AccessModeTemplate::kSet:
+    case VarHandle::AccessModeTemplate::kGetAndUpdate:
+    case VarHandle::AccessModeTemplate::kSet:
       parameters[index++] = varType;
       return index;
   }
   return -1;
 }
 
-// Returns the return type associated with an AccessModeTemplate based
+// Returns the return type associated with an VarHandle::AccessModeTemplate based
 // on the template and the variable type specified.
-static ObjPtr<Class> GetReturnType(AccessModeTemplate access_mode_template, ObjPtr<Class> varType)
+static ObjPtr<Class> GetReturnType(VarHandle::AccessModeTemplate access_mode_template,
+                                   ObjPtr<Class> varType)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   DCHECK(varType != nullptr);
   switch (access_mode_template) {
-    case AccessModeTemplate::kCompareAndSet:
+    case VarHandle::AccessModeTemplate::kCompareAndSet:
       return GetClassRoot(ClassRoot::kPrimitiveBoolean);
-    case AccessModeTemplate::kCompareAndExchange:
-    case AccessModeTemplate::kGet:
-    case AccessModeTemplate::kGetAndUpdate:
+    case VarHandle::AccessModeTemplate::kCompareAndExchange:
+    case VarHandle::AccessModeTemplate::kGet:
+    case VarHandle::AccessModeTemplate::kGetAndUpdate:
       return varType;
-    case AccessModeTemplate::kSet:
+    case VarHandle::AccessModeTemplate::kSet:
       return GetClassRoot(ClassRoot::kPrimitiveVoid);
   }
   return nullptr;
@@ -1647,6 +1554,95 @@
   return true;
 }
 
+// Look up the AccessModeTemplate for a given VarHandle
+// AccessMode. This simplifies finding the correct signature for a
+// VarHandle accessor method.
+VarHandle::AccessModeTemplate VarHandle::GetAccessModeTemplate(VarHandle::AccessMode access_mode) {
+  switch (access_mode) {
+    case VarHandle::AccessMode::kGet:
+      return AccessModeTemplate::kGet;
+    case VarHandle::AccessMode::kSet:
+      return AccessModeTemplate::kSet;
+    case VarHandle::AccessMode::kGetVolatile:
+      return AccessModeTemplate::kGet;
+    case VarHandle::AccessMode::kSetVolatile:
+      return AccessModeTemplate::kSet;
+    case VarHandle::AccessMode::kGetAcquire:
+      return AccessModeTemplate::kGet;
+    case VarHandle::AccessMode::kSetRelease:
+      return AccessModeTemplate::kSet;
+    case VarHandle::AccessMode::kGetOpaque:
+      return AccessModeTemplate::kGet;
+    case VarHandle::AccessMode::kSetOpaque:
+      return AccessModeTemplate::kSet;
+    case VarHandle::AccessMode::kCompareAndSet:
+      return AccessModeTemplate::kCompareAndSet;
+    case VarHandle::AccessMode::kCompareAndExchange:
+      return AccessModeTemplate::kCompareAndExchange;
+    case VarHandle::AccessMode::kCompareAndExchangeAcquire:
+      return AccessModeTemplate::kCompareAndExchange;
+    case VarHandle::AccessMode::kCompareAndExchangeRelease:
+      return AccessModeTemplate::kCompareAndExchange;
+    case VarHandle::AccessMode::kWeakCompareAndSetPlain:
+      return AccessModeTemplate::kCompareAndSet;
+    case VarHandle::AccessMode::kWeakCompareAndSet:
+      return AccessModeTemplate::kCompareAndSet;
+    case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
+      return AccessModeTemplate::kCompareAndSet;
+    case VarHandle::AccessMode::kWeakCompareAndSetRelease:
+      return AccessModeTemplate::kCompareAndSet;
+    case VarHandle::AccessMode::kGetAndSet:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndSetAcquire:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndSetRelease:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndAdd:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndAddAcquire:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndAddRelease:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseOr:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseOrRelease:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseAnd:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseAndRelease:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseXor:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseXorRelease:
+      return AccessModeTemplate::kGetAndUpdate;
+    case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
+      return AccessModeTemplate::kGetAndUpdate;
+  }
+}
+
+VarHandle::AccessModeTemplate VarHandle::GetAccessModeTemplateByIntrinsic(Intrinsics ordinal) {
+  AccessMode access_mode = GetAccessModeByIntrinsic(ordinal);
+  return GetAccessModeTemplate(access_mode);
+}
+
+int32_t VarHandle::GetNumberOfVarTypeParameters(AccessModeTemplate access_mode_template) {
+  switch (access_mode_template) {
+    case AccessModeTemplate::kGet:
+      return 0;
+    case AccessModeTemplate::kSet:
+    case AccessModeTemplate::kGetAndUpdate:
+      return 1;
+    case AccessModeTemplate::kCompareAndSet:
+    case AccessModeTemplate::kCompareAndExchange:
+      return 2;
+  }
+  UNREACHABLE();
+}
+
 ArtField* FieldVarHandle::GetField() {
   return reinterpret_cast64<ArtField*>(GetField64(ArtFieldOffset()));
 }
diff --git a/runtime/mirror/var_handle.h b/runtime/mirror/var_handle.h
index 83cf2e1..c1dcb94 100644
--- a/runtime/mirror/var_handle.h
+++ b/runtime/mirror/var_handle.h
@@ -57,6 +57,12 @@
   // method can take.
   static constexpr size_t kMaxVarTypeParameters = 2;
 
+  // The minimum number of CoordinateType parameters a VarHandle acessor method may take.
+  static constexpr size_t kMinCoordinateTypes = 0;
+
+  // The maximum number of CoordinateType parameters a VarHandle acessor method may take.
+  static constexpr size_t kMaxCoordinateTypes = 2;
+
   // Enumeration of the possible access modes. This mirrors the enum
   // in java.lang.invoke.VarHandle.
   enum class AccessMode : uint32_t {
@@ -95,6 +101,15 @@
   };
   constexpr static size_t kNumberOfAccessModes = static_cast<size_t>(AccessMode::kLast) + 1u;
 
+  // Enumeration for describing the parameter and return types of an AccessMode.
+  enum class AccessModeTemplate : uint32_t {
+    kGet,                 // T Op(C0..CN)
+    kSet,                 // void Op(C0..CN, T)
+    kCompareAndSet,       // boolean Op(C0..CN, T, T)
+    kCompareAndExchange,  // T Op(C0..CN, T, T)
+    kGetAndUpdate,        // T Op(C0..CN, T)
+  };
+
   // Returns true if the AccessMode specified is a supported operation.
   bool IsAccessModeSupported(AccessMode accessMode) REQUIRES_SHARED(Locks::mutator_lock_) {
     return (GetAccessModesBitMask() & (1u << static_cast<uint32_t>(accessMode))) != 0;
@@ -143,6 +158,15 @@
   // VarHandle access method, such as "setOpaque". Returns false otherwise.
   static bool GetAccessModeByMethodName(const char* method_name, AccessMode* access_mode);
 
+  // Returns the AccessModeTemplate for a given mode.
+  static AccessModeTemplate GetAccessModeTemplate(AccessMode access_mode);
+
+  // Returns the AccessModeTemplate corresponding to a VarHandle accessor intrinsic.
+  static AccessModeTemplate GetAccessModeTemplateByIntrinsic(Intrinsics ordinal);
+
+  // Returns the number of VarType parameters for an access mode template.
+  static int32_t GetNumberOfVarTypeParameters(AccessModeTemplate access_mode_template);
+
   static MemberOffset VarTypeOffset() {
     return MemberOffset(OFFSETOF_MEMBER(VarHandle, var_type_));
   }
diff --git a/runtime/mirror/var_handle_test.cc b/runtime/mirror/var_handle_test.cc
index bb67a4a..5e763dd 100644
--- a/runtime/mirror/var_handle_test.cc
+++ b/runtime/mirror/var_handle_test.cc
@@ -417,6 +417,65 @@
   }
 }
 
+TEST_F(VarHandleTest, AccessModeTemplate) {
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGet));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSet));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetVolatile));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetVolatile));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAcquire));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetOpaque));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetOpaque));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndSet));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchange));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchangeAcquire));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchangeRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetPlain));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSet));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSet));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSetAcquire));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSetRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOr));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAnd));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXor));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
+  EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
+            VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
+}
+
 TEST_F(VarHandleTest, StaticFieldVarHandle) {
   Thread * const self = Thread::Current();
   ScopedObjectAccess soa(self);