comparison jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java @ 23749:d6bd0b9cd0b6

remove uses of setAccessible (JDK-8165434)
author Doug Simon <doug.simon@oracle.com>
date Wed, 07 Sep 2016 15:17:13 +0200
parents 1d4ce2d19e52
children
comparison
equal deleted inserted replaced
23748:3e551611f1fc 23749:d6bd0b9cd0b6
22 */ 22 */
23 package jdk.vm.ci.hotspot; 23 package jdk.vm.ci.hotspot;
24 24
25 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; 25 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
26 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; 26 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
27 import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass; 27
28 import java.lang.invoke.MethodHandle;
29 import java.util.Objects;
30
28 import jdk.vm.ci.common.JVMCIError; 31 import jdk.vm.ci.common.JVMCIError;
29 import jdk.vm.ci.meta.ConstantReflectionProvider; 32 import jdk.vm.ci.meta.ConstantReflectionProvider;
30 import jdk.vm.ci.meta.JavaConstant; 33 import jdk.vm.ci.meta.JavaConstant;
31 import jdk.vm.ci.meta.MethodHandleAccessProvider; 34 import jdk.vm.ci.meta.MethodHandleAccessProvider;
32 import jdk.vm.ci.meta.ResolvedJavaField; 35 import jdk.vm.ci.meta.ResolvedJavaField;
44 /** 47 /**
45 * Lazy initialization to break class initialization cycle. Field and method lookup is only 48 * Lazy initialization to break class initialization cycle. Field and method lookup is only
46 * possible after the {@link HotSpotJVMCIRuntime} is fully initialized. 49 * possible after the {@link HotSpotJVMCIRuntime} is fully initialized.
47 */ 50 */
48 static class LazyInitialization { 51 static class LazyInitialization {
52 static final ResolvedJavaType lambdaFormType;
49 static final ResolvedJavaField methodHandleFormField; 53 static final ResolvedJavaField methodHandleFormField;
50 static final ResolvedJavaField lambdaFormVmentryField; 54 static final ResolvedJavaField lambdaFormVmentryField;
51 static final ResolvedJavaMethod lambdaFormCompileToBytecodeMethod;
52 static final HotSpotResolvedJavaField memberNameVmtargetField; 55 static final HotSpotResolvedJavaField memberNameVmtargetField;
53 56
54 /** 57 /**
55 * Search for an instance field with the given name in a class. 58 * Search for an instance field with the given name in a class.
56 * 59 *
57 * @param className name of the class to search in 60 * @param declaringType the type declaring the field
58 * @param fieldName name of the field to be searched 61 * @param fieldName name of the field to be searched
59 * @return resolved java field 62 * @return resolved java field
60 * @throws ClassNotFoundException 63 * @throws NoSuchFieldError
61 */ 64 */
62 private static ResolvedJavaField findFieldInClass(String className, String fieldName) throws ClassNotFoundException { 65 private static ResolvedJavaField findFieldInClass(ResolvedJavaType declaringType, String fieldName, ResolvedJavaType fieldType) {
63 Class<?> clazz = Class.forName(className); 66 ResolvedJavaField[] fields = declaringType.getInstanceFields(false);
64 ResolvedJavaType type = runtime().fromClass(clazz);
65 ResolvedJavaField[] fields = type.getInstanceFields(false);
66 for (ResolvedJavaField field : fields) { 67 for (ResolvedJavaField field : fields) {
67 if (field.getName().equals(fieldName)) { 68 if (field.getName().equals(fieldName)) {
68 return field; 69 return field;
69 } 70 }
70 } 71 }
71 return null; 72 throw new NoSuchFieldError(fieldType.getName() + " " + declaringType + "." + fieldName);
72 } 73 }
73 74
74 private static ResolvedJavaMethod findMethodInClass(String className, String methodName) throws ClassNotFoundException { 75 private static ResolvedJavaType resolveType(Class<?> c) {
75 Class<?> clazz = Class.forName(className); 76 return runtime().fromClass(c);
76 HotSpotResolvedObjectTypeImpl type = fromObjectClass(clazz); 77 }
77 ResolvedJavaMethod result = null; 78
78 for (ResolvedJavaMethod method : type.getDeclaredMethods()) { 79 private static ResolvedJavaType resolveType(String className) throws ClassNotFoundException {
79 if (method.getName().equals(methodName)) { 80 return resolveType(Class.forName(className));
80 assert result == null : "more than one method found: " + className + "." + methodName;
81 result = method;
82 }
83 }
84 assert result != null : "method not found: " + className + "." + methodName;
85 return result;
86 } 81 }
87 82
88 static { 83 static {
89 try { 84 try {
90 methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form"); 85 ResolvedJavaType methodHandleType = resolveType(MethodHandle.class);
91 lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry"); 86 ResolvedJavaType memberNameType = resolveType("java.lang.invoke.MemberName");
92 lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode"); 87 lambdaFormType = resolveType("java.lang.invoke.LambdaForm");
93 memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass("java.lang.invoke.MemberName", "vmtarget"); 88 methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType);
89 lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType);
90 memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass(memberNameType, "vmtarget", resolveType(long.class));
94 } catch (Throwable ex) { 91 } catch (Throwable ex) {
95 throw new JVMCIError(ex); 92 throw new JVMCIError(ex);
96 } 93 }
97 } 94 }
98 } 95 }
132 JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle); 129 JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle);
133 if (lambdaForm == null || lambdaForm.isNull()) { 130 if (lambdaForm == null || lambdaForm.isNull()) {
134 return null; 131 return null;
135 } 132 }
136 133
137 JavaConstant memberName; 134 JavaConstant memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
138 if (forceBytecodeGeneration) { 135 if (memberName.isNull() && forceBytecodeGeneration) {
139 /* Invoke non-public method: MemberName LambdaForm.compileToBytecode() */ 136 Object lf = ((HotSpotObjectConstant) lambdaForm).asObject(LazyInitialization.lambdaFormType);
140 memberName = LazyInitialization.lambdaFormCompileToBytecodeMethod.invoke(lambdaForm, new JavaConstant[0]); 137 compilerToVM().compileToBytecode(Objects.requireNonNull(lf));
141 } else {
142 /* Load non-public field: MemberName LambdaForm.vmentry */
143 memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm); 138 memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm);
139 assert memberName.isNonNull();
144 } 140 }
145 return getTargetMethod(memberName); 141 return getTargetMethod(memberName);
146 } 142 }
147 143
148 @Override 144 @Override