ART: Verifier support for VarHandles

Extends checking of signature polymorphic methods to support VarHandle
accessor methods.

Bug: 65872996
Test: run-test --host 954
Change-Id: I696bfdfbf1cd99f7cd6720cda5911dd4f5e66ada
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 5e5e96b..8d9b82e 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -48,6 +48,7 @@
 #include "mirror/method_type.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
+#include "mirror/var_handle.h"
 #include "reg_type-inl.h"
 #include "register_line-inl.h"
 #include "runtime.h"
@@ -3141,6 +3142,7 @@
       }
       if (!CheckSignaturePolymorphicMethod(called_method) ||
           !CheckSignaturePolymorphicReceiver(inst)) {
+        DCHECK(HasFailures());
         break;
       }
       const uint32_t proto_idx = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc();
@@ -4418,14 +4420,20 @@
 
 bool MethodVerifier::CheckSignaturePolymorphicMethod(ArtMethod* method) {
   mirror::Class* klass = method->GetDeclaringClass();
-  if (klass != mirror::MethodHandle::StaticClass()) {
+  const char* method_name = method->GetName();
+
+  const char* expected_return_descriptor;
+  if (klass == mirror::MethodHandle::StaticClass()) {
+    expected_return_descriptor = mirror::MethodHandle::GetReturnTypeDescriptor(method_name);
+  } else if (klass == mirror::VarHandle::StaticClass()) {
+    expected_return_descriptor = mirror::VarHandle::GetReturnTypeDescriptor(method_name);
+  } else {
     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
-        << "Signature polymorphic method must be declared in java.lang.invoke.MethodClass";
+        << "Signature polymorphic method in unsuppported class: " << klass->PrettyDescriptor();
     return false;
   }
 
-  const char* method_name = method->GetName();
-  if (strcmp(method_name, "invoke") != 0 && strcmp(method_name, "invokeExact") != 0) {
+  if (expected_return_descriptor == nullptr) {
     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
         << "Signature polymorphic method name invalid: " << method_name;
     return false;
@@ -4447,9 +4455,10 @@
   }
 
   const char* return_descriptor = method->GetReturnTypeDescriptor();
-  if (strcmp(return_descriptor, "Ljava/lang/Object;") != 0) {
+  if (strcmp(return_descriptor, expected_return_descriptor) != 0) {
     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
-        << "Signature polymorphic method has unexpected return type: " << return_descriptor;
+        << "Signature polymorphic method has unexpected return type: " << return_descriptor
+        << " != " << expected_return_descriptor;
     return false;
   }
 
@@ -4476,9 +4485,10 @@
         << "invoke-polymorphic receiver has no class: "
         << this_type;
     return false;
-  } else if (!this_type.GetClass()->IsSubClass(mirror::MethodHandle::StaticClass())) {
+  } else if (!this_type.GetClass()->IsSubClass(mirror::MethodHandle::StaticClass()) &&
+             !this_type.GetClass()->IsSubClass(mirror::VarHandle::StaticClass())) {
     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
-        << "invoke-polymorphic receiver is not a subclass of MethodHandle: "
+        << "invoke-polymorphic receiver is not a subclass of MethodHandle or VarHandle: "
         << this_type;
     return false;
   }