8161068: jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest fails
Reviewed-by: never, dnsimon
--- 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
*/