src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File
open Cdiff src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2014, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2014, 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 24,36 ****
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;
--- 24,37 ----
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import java.lang.invoke.MethodHandle;
import jdk.vm.ci.common.JVMCIError;
+ import jdk.vm.ci.common.NativeImageReinitialize;
+ import jdk.vm.ci.hotspot.HotSpotMethodData.VMState;
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;
*** 43,61 ****
public HotSpotMethodHandleAccessProvider(ConstantReflectionProvider constantReflection) {
this.constantReflection = constantReflection;
}
/**
! * 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 ResolvedJavaField methodField;
! static final HotSpotResolvedJavaField vmtargetField;
/**
* Search for an instance field with the given name in a class.
*
* @param declaringType the type declaring the field
--- 44,63 ----
public HotSpotMethodHandleAccessProvider(ConstantReflectionProvider constantReflection) {
this.constantReflection = constantReflection;
}
/**
! * Lazy initialized reflection on {@link MethodHandle} internals. Field and method lookup is
! * only possible after the {@link HotSpotJVMCIRuntime} is fully initialized.
*/
! static final class Internals {
! final ResolvedJavaType lambdaFormType;
! final ResolvedJavaField methodHandleFormField;
! final ResolvedJavaField lambdaFormVmentryField;
! final HotSpotResolvedJavaField callSiteTargetField;
! final ResolvedJavaField methodField;
! final HotSpotResolvedJavaField vmtargetField;
/**
* Search for an instance field with the given name in a class.
*
* @param declaringType the type declaring the field
*** 69,105 ****
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);
! ResolvedJavaType methodType = resolveType("java.lang.invoke.ResolvedMethodName");
methodField = findFieldInClass(memberNameType, "method", methodType);
! vmtargetField = (HotSpotResolvedJavaField) findFieldInClass(methodType, "vmtarget", resolveType(HotSpotJVMCIRuntime.getHostWordKind().toJavaClass()));
} catch (Throwable ex) {
throw new JVMCIError(ex);
}
}
}
@Override
public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) {
int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId();
if (intrinsicId != 0) {
--- 71,126 ----
for (ResolvedJavaField field : fields) {
if (field.getName().equals(fieldName) && field.getType().equals(fieldType)) {
return field;
}
}
! throw new NoSuchFieldError(declaringType + "." + fieldName);
}
! private static ResolvedJavaType resolveType(String className) {
! return (ResolvedJavaType) runtime().lookupTypeInternal(className, null, true);
}
! private Internals() {
try {
! ResolvedJavaType methodHandleType = resolveType("Ljava/lang/invoke/MethodHandle;");
! ResolvedJavaType memberNameType = resolveType("Ljava/lang/invoke/MemberName;");
! lambdaFormType = resolveType("Ljava/lang/invoke/LambdaForm;");
methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType);
lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType);
!
! ResolvedJavaType methodType = resolveType("Ljava/lang/invoke/ResolvedMethodName;");
methodField = findFieldInClass(memberNameType, "method", methodType);
! vmtargetField = (HotSpotResolvedJavaField) findFieldInClass(methodType, "vmtarget", resolveType(Character.toString(HotSpotJVMCIRuntime.getHostWordKind().getTypeChar())));
+ ResolvedJavaType callSiteType = resolveType("Ljava/lang/invoke/CallSite;");
+ callSiteTargetField = (HotSpotResolvedJavaField) findFieldInClass(callSiteType, "target", methodHandleType);
} catch (Throwable ex) {
throw new JVMCIError(ex);
}
}
+
+ /**
+ * Singleton instance lazily initialized via double-checked locking.
+ */
+ @NativeImageReinitialize private static volatile Internals instance;
+
+ static Internals instance() {
+ Internals result = instance;
+ if (result == null) {
+ synchronized (VMState.class) {
+ result = instance;
+ if (result == null) {
+ instance = result = new Internals();
}
+ }
+ }
+ return result;
+ }
+
+ }
+
@Override
public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) {
int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId();
if (intrinsicId != 0) {
*** 129,160 ****
if (methodHandle.isNull()) {
return null;
}
/* Load non-public field: LambdaForm MethodHandle.form */
! 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();
}
! JavaConstant method = constantReflection.readFieldValue(LazyInitialization.methodField, memberName);
return getTargetMethod(method);
}
@Override
public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) {
if (memberName.isNull()) {
return null;
}
! JavaConstant method = constantReflection.readFieldValue(LazyInitialization.methodField, memberName);
return getTargetMethod(method);
}
/**
* Returns the {@link ResolvedJavaMethod} for the method of a java.lang.invoke.MemberName.
--- 150,181 ----
if (methodHandle.isNull()) {
return null;
}
/* Load non-public field: LambdaForm MethodHandle.form */
! Internals internals = Internals.instance();
! JavaConstant lambdaForm = constantReflection.readFieldValue(internals.methodHandleFormField, methodHandle);
if (lambdaForm == null || lambdaForm.isNull()) {
return null;
}
! JavaConstant memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm);
if (memberName.isNull() && forceBytecodeGeneration) {
! compilerToVM().compileToBytecode((HotSpotObjectConstantImpl) lambdaForm);
! memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm);
assert memberName.isNonNull();
}
! JavaConstant method = constantReflection.readFieldValue(internals.methodField, memberName);
return getTargetMethod(method);
}
@Override
public ResolvedJavaMethod resolveLinkToTarget(JavaConstant memberName) {
if (memberName.isNull()) {
return null;
}
! JavaConstant method = constantReflection.readFieldValue(Internals.instance().methodField, memberName);
return getTargetMethod(method);
}
/**
* Returns the {@link ResolvedJavaMethod} for the method of a java.lang.invoke.MemberName.
*** 163,172 ****
if (method == null) {
// If readFieldValue returns NULL the type was wrong
throw new IllegalArgumentException("unexpected type for memberName");
}
- Object object = ((HotSpotObjectConstantImpl) method).object();
/* Read the ResolvedJavaMethod from the injected field MemberName.method.vmtarget */
! return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.vmtargetField.getOffset());
}
}
--- 184,192 ----
if (method == null) {
// If readFieldValue returns NULL the type was wrong
throw new IllegalArgumentException("unexpected type for memberName");
}
/* Read the ResolvedJavaMethod from the injected field MemberName.method.vmtarget */
! return compilerToVM().getResolvedJavaMethod((HotSpotObjectConstantImpl) method, Internals.instance().vmtargetField.getOffset());
}
}
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File