# HG changeset patch # User mhaupt # Date 1468477988 -7200 # Node ID 813343dec9dd379c6de6f4611892f8a203e6c9ed # Parent 3b21b3295f19184718e5455395f88b6b937635d2 8161068: jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest fails Reviewed-by: never, dnsimon diff -r 3b21b3295f19 -r 813343dec9dd hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.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()); } } + diff -r 3b21b3295f19 -r 813343dec9dd hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java --- 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 */