8161068: jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest fails
Reviewed-by: never, dnsimon
This commit is contained in:
parent
684f63ba14
commit
558ac48a19
@ -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 static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
|
||||
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 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv
|
||||
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 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv
|
||||
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 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv
|
||||
return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user