< prev index next >
src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java
Print this page
*** 22,41 ****
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
! 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 {
private final ConstantReflectionProvider constantReflection;
--- 22,42 ----
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
!
! import java.lang.invoke.MethodHandle;
! import java.util.Objects;
!
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider {
private final ConstantReflectionProvider constantReflection;
*** 46,137 ****
/**
* Lazy initialization to break class initialization cycle. Field and method lookup is only
* possible after the {@link HotSpotJVMCIRuntime} is fully initialized.
*/
static class LazyInitialization {
static final ResolvedJavaField methodHandleFormField;
static final ResolvedJavaField lambdaFormVmentryField;
- 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
* @param fieldType resolved Java type of the field
* @return resolved Java field
- * @throws ClassNotFoundException
* @throws NoSuchFieldError
*/
! 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) && field.getType().equals(fieldType)) {
return field;
}
}
! throw new NoSuchFieldError(fieldType.getName() + " " + className + "." + fieldName);
}
! 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) && signatureMatches(method, resultType, parameterTypes)) {
! result = method;
! }
! }
! 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;
! }
! if (s.getParameterCount(false) != parameterTypes.length) {
! 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",
! 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);
}
}
}
--- 47,96 ----
/**
* Lazy initialization to break class initialization cycle. Field and method lookup is only
* possible after the {@link HotSpotJVMCIRuntime} is fully initialized.
*/
static class LazyInitialization {
+ static final ResolvedJavaType lambdaFormType;
static final ResolvedJavaField methodHandleFormField;
static final ResolvedJavaField lambdaFormVmentryField;
static final HotSpotResolvedJavaField memberNameVmtargetField;
/**
* Search for an instance field with the given name in a class.
*
! * @param declaringType the type declaring the field
* @param fieldName name of the field to be searched
* @param fieldType resolved Java type of the field
* @return resolved Java field
* @throws NoSuchFieldError
*/
! private static ResolvedJavaField findFieldInClass(ResolvedJavaType declaringType, String fieldName, ResolvedJavaType fieldType) {
! ResolvedJavaField[] fields = declaringType.getInstanceFields(false);
for (ResolvedJavaField field : fields) {
if (field.getName().equals(fieldName) && field.getType().equals(fieldType)) {
return field;
}
}
! throw new NoSuchFieldError(fieldType.getName() + " " + declaringType + "." + fieldName);
}
! private static ResolvedJavaType resolveType(Class<?> c) {
! return runtime().fromClass(c);
}
! private static ResolvedJavaType resolveType(String className) throws ClassNotFoundException {
! return resolveType(Class.forName(className));
}
static {
try {
! ResolvedJavaType methodHandleType = resolveType(MethodHandle.class);
! ResolvedJavaType memberNameType = resolveType("java.lang.invoke.MemberName");
! lambdaFormType = resolveType("java.lang.invoke.LambdaForm");
! methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType);
! lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType);
! memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass(memberNameType, "vmtarget", resolveType(long.class));
} catch (Throwable ex) {
throw new JVMCIError(ex);
}
}
}
*** 171,186 ****
JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle);
if (lambdaForm == null || lambdaForm.isNull()) {
return null;
}
! if (forceBytecodeGeneration) {
! /* Invoke non-public method: MemberName LambdaForm.compileToBytecode() */
! LazyInitialization.lambdaFormCompileToBytecodeMethod.invoke(lambdaForm, new JavaConstant[0]);
}
/* Load non-public field: MemberName LambdaForm.vmentry */
- JavaConstant memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
return getTargetMethod(memberName);
}
@Override
public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) {
--- 130,147 ----
JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle);
if (lambdaForm == null || lambdaForm.isNull()) {
return null;
}
! JavaConstant memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
! if (memberName.isNull() && forceBytecodeGeneration) {
! Object lf = ((HotSpotObjectConstant) lambdaForm).asObject(LazyInitialization.lambdaFormType);
! compilerToVM().compileToBytecode(Objects.requireNonNull(lf));
! memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
! assert memberName.isNonNull();
}
/* Load non-public field: MemberName LambdaForm.vmentry */
return getTargetMethod(memberName);
}
@Override
public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) {
*** 198,203 ****
Object object = ((HotSpotObjectConstantImpl) memberName).object();
/* Read the ResolvedJavaMethod from the injected field MemberName.vmtarget */
return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
}
}
-
--- 159,163 ----
< prev index next >