8161068: jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest fails
authormhaupt
Thu, 14 Jul 2016 08:33:08 +0200
changeset 40063 813343dec9dd
parent 40062 3b21b3295f19
child 40066 0273d5b3d548
child 40067 db6c74a53556
8161068: jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest fails Reviewed-by: never, dnsimon
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java
hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Wed Jul 13 19:08:07 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Thu Jul 14 08:33:08 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,12 @@
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MethodHandleAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
 
 public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider {
 
@@ -51,46 +53,80 @@
         static final ResolvedJavaMethod lambdaFormCompileToBytecodeMethod;
         static final HotSpotResolvedJavaField memberNameVmtargetField;
 
+        static final ResolvedJavaType CLASS = fromObjectClass(LazyInitialization.class);
+
         /**
          * Search for an instance field with the given name in a class.
          *
          * @param className name of the class to search in
          * @param fieldName name of the field to be searched
-         * @return resolved java field
+         * @param fieldType resolved Java type of the field
+         * @return resolved Java field
          * @throws ClassNotFoundException
+         * @throws NoSuchFieldError
          */
-        private static ResolvedJavaField findFieldInClass(String className, String fieldName) throws ClassNotFoundException {
+        private static ResolvedJavaField findFieldInClass(String className, String fieldName, ResolvedJavaType fieldType)
+                throws ClassNotFoundException {
             Class<?> clazz = Class.forName(className);
             ResolvedJavaType type = runtime().fromClass(clazz);
             ResolvedJavaField[] fields = type.getInstanceFields(false);
             for (ResolvedJavaField field : fields) {
-                if (field.getName().equals(fieldName)) {
+                if (field.getName().equals(fieldName) && field.getType().equals(fieldType)) {
                     return field;
                 }
             }
-            return null;
+            throw new NoSuchFieldError(fieldType.getName() + " " + className + "." + fieldName);
         }
 
-        private static ResolvedJavaMethod findMethodInClass(String className, String methodName) throws ClassNotFoundException {
+        private static ResolvedJavaMethod findMethodInClass(String className, String methodName,
+                ResolvedJavaType resultType, ResolvedJavaType[] parameterTypes) throws ClassNotFoundException {
             Class<?> clazz = Class.forName(className);
             HotSpotResolvedObjectTypeImpl type = fromObjectClass(clazz);
             ResolvedJavaMethod result = null;
             for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
-                if (method.getName().equals(methodName)) {
-                    assert result == null : "more than one method found: " + className + "." + methodName;
+                if (method.getName().equals(methodName) && signatureMatches(method, resultType, parameterTypes)) {
                     result = method;
                 }
             }
-            assert result != null : "method not found: " + className + "." + methodName;
+            if (result == null) {
+                StringBuilder sig = new StringBuilder("(");
+                for (ResolvedJavaType t : parameterTypes) {
+                    sig.append(t.getName()).append(",");
+                }
+                if (sig.length() > 1) {
+                    sig.replace(sig.length() - 1, sig.length(), ")");
+                } else {
+                    sig.append(')');
+                }
+                throw new NoSuchMethodError(resultType.getName() + " " + className + "." + methodName + sig.toString());
+            }
             return result;
         }
 
+        private static boolean signatureMatches(ResolvedJavaMethod m, ResolvedJavaType resultType,
+                ResolvedJavaType[] parameterTypes) {
+            Signature s = m.getSignature();
+            if (!s.getReturnType(CLASS).equals(resultType)) {
+                return false;
+            }
+            for (int i = 0; i < s.getParameterCount(false); ++i) {
+                if (!s.getParameterType(i, CLASS).equals(parameterTypes[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
         static {
             try {
-                methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form");
-                lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry");
-                lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode");
-                memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass("java.lang.invoke.MemberName", "vmtarget");
+                methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form",
+                    fromObjectClass(Class.forName("java.lang.invoke.LambdaForm")));
+                lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry",
+                    fromObjectClass(Class.forName("java.lang.invoke.MemberName")));
+                lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode",
+                    new HotSpotResolvedPrimitiveType(JavaKind.Void), new ResolvedJavaType[]{});
+                memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass("java.lang.invoke.MemberName", "vmtarget",
+                    new HotSpotResolvedPrimitiveType(JavaKind.Long));
             } catch (Throwable ex) {
                 throw new JVMCIError(ex);
             }
@@ -134,14 +170,12 @@
             return null;
         }
 
-        JavaConstant memberName;
         if (forceBytecodeGeneration) {
             /* Invoke non-public method: MemberName LambdaForm.compileToBytecode() */
-            memberName = LazyInitialization.lambdaFormCompileToBytecodeMethod.invoke(lambdaForm, new JavaConstant[0]);
-        } else {
-            /* Load non-public field: MemberName LambdaForm.vmentry */
-            memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
+            LazyInitialization.lambdaFormCompileToBytecodeMethod.invoke(lambdaForm, new JavaConstant[0]);
         }
+        /* Load non-public field: MemberName LambdaForm.vmentry */
+        JavaConstant memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
         return getTargetMethod(memberName);
     }
 
@@ -163,3 +197,4 @@
         return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
     }
 }
+
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java	Wed Jul 13 19:08:07 2016 +0300
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java	Thu Jul 14 08:33:08 2016 +0200
@@ -24,12 +24,12 @@
 /*
  * @test
  * @bug 8152343
+ * @bug 8161068
  * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64")
  * @library /testlibrary /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src
  * @modules jdk.vm.ci/jdk.vm.ci.meta
  *          jdk.vm.ci/jdk.vm.ci.runtime
  *          jdk.vm.ci/jdk.vm.ci.hotspot
- * @ignore 8161068
  * @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
  *      jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest
  */