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> (¶meters)[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);