8215748: Application fails when executed with Graal
authornever
Tue, 15 Jan 2019 22:59:33 -0800
changeset 53352 ac431929db51
parent 53351 bdb29aa5fd31
child 53353 a6620d37728b
8215748: Application fails when executed with Graal Reviewed-by: iveresov, kvn, thartmann
src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed Jan 16 11:25:55 2019 +0800
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Tue Jan 15 22:59:33 2019 -0800
@@ -602,6 +602,17 @@
       return NULL;
   }
 
+  if (method->name() == vmSymbols::clone_name() &&
+      resolved == SystemDictionary::Object_klass() &&
+      recv_klass->is_array_klass()) {
+    // Resolution of the clone method on arrays always returns Object.clone even though that method
+    // has protected access.  There's some trickery in the access checking to make this all work out
+    // so it's necessary to pass in the array class as the resolved class to properly trigger this.
+    // Otherwise it's impossible to resolve the array clone methods through JVMCI.  See
+    // LinkResolver::check_method_accessability for the matching logic.
+    resolved = recv_klass;
+  }
+
   LinkInfo link_info(resolved, h_name, h_signature, caller_klass);
   methodHandle m;
   // Only do exact lookup if receiver klass has been linked.  Otherwise,
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java	Wed Jan 16 11:25:55 2019 +0800
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java	Tue Jan 15 22:59:33 2019 -0800
@@ -168,6 +168,26 @@
 
     }
 
+    static class ClassType {
+    }
+
+    interface InterfaceType {
+    }
+
+    @Test
+    public void testCloneAccessibility() {
+        /*
+         * The resolution machinery for clone on arrays has some hacks in that show up in odd places
+         * so make sure that resolveMethod works as expected.
+         */
+        ResolvedJavaType interfaceType = getType(InterfaceType.class);
+        ResolvedJavaType classType = getType(ClassType.class);
+        ResolvedJavaType arrayType = getType(double[].class);
+        ResolvedJavaMethod cloneMethod = getMethod(getType(Object.class), "clone");
+        assertEquals("Can't resolve clone for class", cloneMethod, arrayType.resolveMethod(cloneMethod, classType));
+        assertEquals("Can't resolve clone for interface", cloneMethod, arrayType.resolveMethod(cloneMethod, interfaceType));
+    }
+
     static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) {
         for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
             if (method.getName().equals(methodName)) {