# HG changeset patch # Parent 25442c9a17c81086fe33fde7446fbb54a7d50f0d 8161068: jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest fails diff -r 25442c9a17c8 src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java Thu Jul 07 18:35:44 2016 +0000 +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java Mon Jul 11 09:31:49 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 @@ -27,11 +27,15 @@ import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.hotspot.HotSpotResolvedPrimitiveType; import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; 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,6 +55,8 @@ 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. * @@ -59,25 +65,26 @@ * @return resolved java field * @throws ClassNotFoundException */ - 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; } - 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; } } @@ -85,12 +92,30 @@ 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); } @@ -137,11 +162,10 @@ 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 */ + memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm); return getTargetMethod(memberName); }