26 package sun.dyn; |
26 package sun.dyn; |
27 |
27 |
28 import java.dyn.CallSite; |
28 import java.dyn.CallSite; |
29 import java.dyn.MethodHandle; |
29 import java.dyn.MethodHandle; |
30 import java.dyn.MethodType; |
30 import java.dyn.MethodType; |
|
31 import java.dyn.MethodHandles.Lookup; |
31 import java.lang.reflect.AccessibleObject; |
32 import java.lang.reflect.AccessibleObject; |
32 import java.lang.reflect.Field; |
33 import java.lang.reflect.Field; |
33 import static sun.dyn.MethodHandleNatives.Constants.*; |
34 import static sun.dyn.MethodHandleNatives.Constants.*; |
|
35 import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP; |
34 |
36 |
35 /** |
37 /** |
36 * The JVM interface for the method handles package is all here. |
38 * The JVM interface for the method handles package is all here. |
|
39 * This is an interface internal and private to an implemetantion of JSR 292. |
|
40 * <em>This class is not part of the JSR 292 standard.</em> |
37 * @author jrose |
41 * @author jrose |
38 */ |
42 */ |
39 class MethodHandleNatives { |
43 class MethodHandleNatives { |
40 |
44 |
41 private MethodHandleNatives() { } // static only |
45 private MethodHandleNatives() { } // static only |
58 static native void init(DirectMethodHandle self, Object ref, boolean doDispatch, Class<?> caller); |
62 static native void init(DirectMethodHandle self, Object ref, boolean doDispatch, Class<?> caller); |
59 |
63 |
60 /** Initialize a method type, once per form. */ |
64 /** Initialize a method type, once per form. */ |
61 static native void init(MethodType self); |
65 static native void init(MethodType self); |
62 |
66 |
|
67 /** Tell the JVM about a class's bootstrap method. */ |
|
68 static native void registerBootstrap(Class<?> caller, MethodHandle bootstrapMethod); |
|
69 |
|
70 /** Ask the JVM about a class's bootstrap method. */ |
|
71 static native MethodHandle getBootstrap(Class<?> caller); |
|
72 |
63 /** Tell the JVM that we need to change the target of an invokedynamic. */ |
73 /** Tell the JVM that we need to change the target of an invokedynamic. */ |
64 static native void linkCallSite(CallSite site, MethodHandle target); |
74 static native void setCallSiteTarget(CallSite site, MethodHandle target); |
65 |
75 |
66 /** Fetch the vmtarget field. |
76 /** Fetch the vmtarget field. |
67 * It will be sanitized as necessary to avoid exposing non-Java references. |
77 * It will be sanitized as necessary to avoid exposing non-Java references. |
68 * This routine is for debugging and reflection. |
78 * This routine is for debugging and reflection. |
69 */ |
79 */ |
111 /** Java copy of MethodHandlePushLimit in range 2..255. */ |
121 /** Java copy of MethodHandlePushLimit in range 2..255. */ |
112 static final int JVM_PUSH_LIMIT; |
122 static final int JVM_PUSH_LIMIT; |
113 /** JVM stack motion (in words) after one slot is pushed, usually -1. |
123 /** JVM stack motion (in words) after one slot is pushed, usually -1. |
114 */ |
124 */ |
115 static final int JVM_STACK_MOVE_UNIT; |
125 static final int JVM_STACK_MOVE_UNIT; |
|
126 |
|
127 /** Which conv-ops are implemented by the JVM? */ |
|
128 static final int CONV_OP_IMPLEMENTED_MASK; |
116 |
129 |
117 private static native void registerNatives(); |
130 private static native void registerNatives(); |
118 static { |
131 static { |
119 boolean JVM_SUPPORT_; |
132 boolean JVM_SUPPORT_; |
120 int JVM_PUSH_LIMIT_; |
133 int JVM_PUSH_LIMIT_; |
121 int JVM_STACK_MOVE_UNIT_; |
134 int JVM_STACK_MOVE_UNIT_; |
|
135 int CONV_OP_IMPLEMENTED_MASK_; |
122 try { |
136 try { |
123 registerNatives(); |
137 registerNatives(); |
124 JVM_SUPPORT_ = true; |
138 JVM_SUPPORT_ = true; |
125 JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT); |
139 JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT); |
126 JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT); |
140 JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT); |
|
141 CONV_OP_IMPLEMENTED_MASK_ = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK); |
127 //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init"); |
142 //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init"); |
128 } catch (UnsatisfiedLinkError ee) { |
143 } catch (UnsatisfiedLinkError ee) { |
129 // ignore; if we use init() methods later we'll see linkage errors |
144 // ignore; if we use init() methods later we'll see linkage errors |
130 JVM_SUPPORT_ = false; |
145 JVM_SUPPORT_ = false; |
131 JVM_PUSH_LIMIT_ = 3; // arbitrary |
146 JVM_PUSH_LIMIT_ = 3; // arbitrary |
132 JVM_STACK_MOVE_UNIT_ = -1; // arbitrary |
147 JVM_STACK_MOVE_UNIT_ = -1; // arbitrary |
|
148 CONV_OP_IMPLEMENTED_MASK_ = 0; |
133 //System.out.println("Warning: Running with JVM_SUPPORT=false"); |
149 //System.out.println("Warning: Running with JVM_SUPPORT=false"); |
134 //System.out.println(ee); |
150 //System.out.println(ee); |
135 JVM_SUPPORT = JVM_SUPPORT_; |
151 JVM_SUPPORT = JVM_SUPPORT_; |
136 JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; |
152 JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; |
137 JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; |
153 JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; |
138 throw ee; // just die; hopeless to try to run with an older JVM |
154 throw ee; // just die; hopeless to try to run with an older JVM |
139 } |
155 } |
140 JVM_SUPPORT = JVM_SUPPORT_; |
156 JVM_SUPPORT = JVM_SUPPORT_; |
141 JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; |
157 JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; |
142 JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; |
158 JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; |
|
159 if (CONV_OP_IMPLEMENTED_MASK_ == 0) |
|
160 CONV_OP_IMPLEMENTED_MASK_ = DEFAULT_CONV_OP_IMPLEMENTED_MASK; |
|
161 CONV_OP_IMPLEMENTED_MASK = CONV_OP_IMPLEMENTED_MASK_; |
143 } |
162 } |
144 |
163 |
145 // All compile-time constants go here. |
164 // All compile-time constants go here. |
146 // There is an opportunity to check them against the JVM's idea of them. |
165 // There is an opportunity to check them against the JVM's idea of them. |
147 static class Constants { |
166 static class Constants { |
148 Constants() { } // static only |
167 Constants() { } // static only |
149 // MethodHandleImpl |
168 // MethodHandleImpl |
150 static final int // for getConstant |
169 static final int // for getConstant |
151 GC_JVM_PUSH_LIMIT = 0, |
170 GC_JVM_PUSH_LIMIT = 0, |
152 GC_JVM_STACK_MOVE_UNIT = 1; |
171 GC_JVM_STACK_MOVE_UNIT = 1, |
|
172 GC_CONV_OP_IMPLEMENTED_MASK = 2; |
153 static final int |
173 static final int |
154 ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) |
174 ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) |
155 ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self) |
175 ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self) |
156 ETF_METHOD_NAME = 2, // ultimate method as MemberName |
176 ETF_METHOD_NAME = 2, // ultimate method as MemberName |
157 ETF_REFLECT_METHOD = 3; // ultimate method as java.lang.reflect object (sans refClass) |
177 ETF_REFLECT_METHOD = 3; // ultimate method as java.lang.reflect object (sans refClass) |
204 CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed) |
224 CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed) |
205 CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change |
225 CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change |
206 CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1; |
226 CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1; |
207 |
227 |
208 /** Which conv-ops are implemented by the JVM? */ |
228 /** Which conv-ops are implemented by the JVM? */ |
209 static final int CONV_OP_IMPLEMENTED_MASK = |
229 static final int DEFAULT_CONV_OP_IMPLEMENTED_MASK = |
210 // TODO: The following expression should be replaced by |
230 // Value to use if the corresponding JVM query fails. |
211 // a JVM query. |
|
212 ((1<<OP_RETYPE_ONLY) |
231 ((1<<OP_RETYPE_ONLY) |
213 |(1<<OP_RETYPE_RAW) |
232 |(1<<OP_RETYPE_RAW) |
214 |(1<<OP_CHECK_CAST) |
233 |(1<<OP_CHECK_CAST) |
215 |(1<<OP_PRIM_TO_PRIM) |
234 |(1<<OP_PRIM_TO_PRIM) |
216 |(1<<OP_REF_TO_PRIM) |
235 |(1<<OP_REF_TO_PRIM) |
217 |(1<<OP_SWAP_ARGS) |
236 |(1<<OP_SWAP_ARGS) |
218 |(1<<OP_ROT_ARGS) |
237 |(1<<OP_ROT_ARGS) |
219 |(1<<OP_DUP_ARGS) |
238 |(1<<OP_DUP_ARGS) |
220 |(1<<OP_DROP_ARGS) |
239 |(1<<OP_DROP_ARGS) |
221 //|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code. |
240 //|(1<<OP_SPREAD_ARGS) |
222 ); |
241 ); |
223 |
242 |
224 /** |
243 /** |
225 * Basic types as encoded in the JVM. These code values are not |
244 * Basic types as encoded in the JVM. These code values are not |
226 * intended for use outside this class. They are used as part of |
245 * intended for use outside this class. They are used as part of |
261 return true; |
280 return true; |
262 } |
281 } |
263 static { |
282 static { |
264 if (JVM_SUPPORT) verifyConstants(); |
283 if (JVM_SUPPORT) verifyConstants(); |
265 } |
284 } |
|
285 |
|
286 // Up-calls from the JVM. |
|
287 // These must NOT be public. |
|
288 |
|
289 /** |
|
290 * The JVM is linking an invokedynamic instruction. Create a reified call site for it. |
|
291 */ |
|
292 static CallSite makeDynamicCallSite(MethodHandle bootstrapMethod, |
|
293 String name, MethodType type, |
|
294 Object info, |
|
295 MemberName callerMethod, int callerBCI) { |
|
296 return CallSiteImpl.makeSite(bootstrapMethod, name, type, info, callerMethod, callerBCI); |
|
297 } |
|
298 |
|
299 /** |
|
300 * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one. |
|
301 */ |
|
302 static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) { |
|
303 MethodType.genericMethodType(0); // trigger initialization |
|
304 return MethodTypeImpl.makeImpl(Access.TOKEN, rtype, ptypes, true); |
|
305 } |
|
306 |
266 } |
307 } |