30 // JVM support for MethodHandle, MethodType, and related types |
30 // JVM support for MethodHandle, MethodType, and related types |
31 // in java.dyn and java.dyn.hotspot. |
31 // in java.dyn and java.dyn.hotspot. |
32 // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}. |
32 // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}. |
33 public: |
33 public: |
34 enum EntryKind { |
34 enum EntryKind { |
35 _check_mtype, // how a caller calls a MH |
35 _raise_exception, // stub for error generation from other stubs |
36 _wrong_method_type, // what happens when there is a type mismatch |
|
37 _invokestatic_mh, // how a MH emulates invokestatic |
36 _invokestatic_mh, // how a MH emulates invokestatic |
38 _invokespecial_mh, // ditto for the other invokes... |
37 _invokespecial_mh, // ditto for the other invokes... |
39 _invokevirtual_mh, |
38 _invokevirtual_mh, |
40 _invokeinterface_mh, |
39 _invokeinterface_mh, |
41 _bound_ref_mh, // reference argument is bound |
40 _bound_ref_mh, // reference argument is bound |
45 _bound_int_direct_mh, |
44 _bound_int_direct_mh, |
46 _bound_long_direct_mh, |
45 _bound_long_direct_mh, |
47 |
46 |
48 _adapter_mh_first, // adapter sequence goes here... |
47 _adapter_mh_first, // adapter sequence goes here... |
49 _adapter_retype_only = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY, |
48 _adapter_retype_only = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY, |
|
49 _adapter_retype_raw = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW, |
50 _adapter_check_cast = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST, |
50 _adapter_check_cast = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST, |
51 _adapter_prim_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM, |
51 _adapter_prim_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM, |
52 _adapter_ref_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM, |
52 _adapter_ref_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM, |
53 _adapter_prim_to_ref = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF, |
53 _adapter_prim_to_ref = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF, |
54 _adapter_swap_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS, |
54 _adapter_swap_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS, |
127 |
129 |
128 static void init_entry(EntryKind ek, MethodHandleEntry* me) { |
130 static void init_entry(EntryKind ek, MethodHandleEntry* me) { |
129 assert(ek_valid(ek), "oob"); |
131 assert(ek_valid(ek), "oob"); |
130 assert(_entries[ek] == NULL, "no double initialization"); |
132 assert(_entries[ek] == NULL, "no double initialization"); |
131 _entries[ek] = me; |
133 _entries[ek] = me; |
|
134 } |
|
135 |
|
136 static methodOop raise_exception_method() { |
|
137 oop rem = JNIHandles::resolve(_raise_exception_method); |
|
138 assert(rem == NULL || rem->is_method(), ""); |
|
139 return (methodOop) rem; |
|
140 } |
|
141 static void set_raise_exception_method(methodOop rem) { |
|
142 assert(_raise_exception_method == NULL, ""); |
|
143 _raise_exception_method = JNIHandles::make_global(Handle(rem)); |
132 } |
144 } |
133 |
145 |
134 static jint adapter_conversion(int conv_op, BasicType src, BasicType dest, |
146 static jint adapter_conversion(int conv_op, BasicType src, BasicType dest, |
135 int stack_move = 0, int vminfo = 0) { |
147 int stack_move = 0, int vminfo = 0) { |
136 assert(conv_op_valid(conv_op), "oob"); |
148 assert(conv_op_valid(conv_op), "oob"); |
241 }; |
253 }; |
242 static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result); |
254 static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result); |
243 enum { |
255 enum { |
244 // format of query to getConstant: |
256 // format of query to getConstant: |
245 GC_JVM_PUSH_LIMIT = 0, |
257 GC_JVM_PUSH_LIMIT = 0, |
246 GC_JVM_STACK_MOVE_LIMIT = 1, |
258 GC_JVM_STACK_MOVE_UNIT = 1, |
247 |
259 |
248 // format of result from getTarget / encode_target: |
260 // format of result from getTarget / encode_target: |
249 ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) |
261 ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) |
250 ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self) |
262 ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self) |
251 ETF_METHOD_NAME = 2, // ultimate method as MemberName |
263 ETF_METHOD_NAME = 2, // ultimate method as MemberName |
259 // These checkers operate on a pair of whole MethodTypes: |
271 // These checkers operate on a pair of whole MethodTypes: |
260 static const char* check_method_type_change(oop src_mtype, int src_beg, int src_end, |
272 static const char* check_method_type_change(oop src_mtype, int src_beg, int src_end, |
261 int insert_argnum, oop insert_type, |
273 int insert_argnum, oop insert_type, |
262 int change_argnum, oop change_type, |
274 int change_argnum, oop change_type, |
263 int delete_argnum, |
275 int delete_argnum, |
264 oop dst_mtype, int dst_beg, int dst_end); |
276 oop dst_mtype, int dst_beg, int dst_end, |
|
277 bool raw = false); |
265 static const char* check_method_type_insertion(oop src_mtype, |
278 static const char* check_method_type_insertion(oop src_mtype, |
266 int insert_argnum, oop insert_type, |
279 int insert_argnum, oop insert_type, |
267 oop dst_mtype) { |
280 oop dst_mtype) { |
268 oop no_ref = NULL; |
281 oop no_ref = NULL; |
269 return check_method_type_change(src_mtype, 0, -1, |
282 return check_method_type_change(src_mtype, 0, -1, |
276 oop no_ref = NULL; |
289 oop no_ref = NULL; |
277 return check_method_type_change(src_mtype, 0, -1, -1, no_ref, |
290 return check_method_type_change(src_mtype, 0, -1, -1, no_ref, |
278 change_argnum, change_type, |
291 change_argnum, change_type, |
279 -1, dst_mtype, 0, -1); |
292 -1, dst_mtype, 0, -1); |
280 } |
293 } |
281 static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype) { |
294 static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype, bool raw) { |
282 oop no_ref = NULL; |
295 oop no_ref = NULL; |
283 return check_method_type_change(src_mtype, 0, -1, |
296 return check_method_type_change(src_mtype, 0, -1, |
284 -1, no_ref, -1, no_ref, -1, |
297 -1, no_ref, -1, no_ref, -1, |
285 dst_mtype, 0, -1); |
298 dst_mtype, 0, -1, raw); |
286 } |
299 } |
287 |
300 |
288 // These checkers operate on pairs of argument or return types: |
301 // These checkers operate on pairs of argument or return types: |
289 static const char* check_argument_type_change(BasicType src_type, klassOop src_klass, |
302 static const char* check_argument_type_change(BasicType src_type, klassOop src_klass, |
290 BasicType dst_type, klassOop dst_klass, |
303 BasicType dst_type, klassOop dst_klass, |
291 int argnum); |
304 int argnum, bool raw = false); |
292 |
305 |
293 static const char* check_argument_type_change(oop src_type, oop dst_type, |
306 static const char* check_argument_type_change(oop src_type, oop dst_type, |
294 int argnum) { |
307 int argnum, bool raw = false) { |
295 klassOop src_klass = NULL, dst_klass = NULL; |
308 klassOop src_klass = NULL, dst_klass = NULL; |
296 BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass); |
309 BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass); |
297 BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass); |
310 BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass); |
298 return check_argument_type_change(src_bt, src_klass, |
311 return check_argument_type_change(src_bt, src_klass, |
299 dst_bt, dst_klass, argnum); |
312 dst_bt, dst_klass, argnum, raw); |
300 } |
313 } |
301 |
314 |
302 static const char* check_return_type_change(oop src_type, oop dst_type) { |
315 static const char* check_return_type_change(oop src_type, oop dst_type, bool raw = false) { |
303 return check_argument_type_change(src_type, dst_type, -1); |
316 return check_argument_type_change(src_type, dst_type, -1, raw); |
304 } |
317 } |
305 |
318 |
306 static const char* check_return_type_change(BasicType src_type, klassOop src_klass, |
319 static const char* check_return_type_change(BasicType src_type, klassOop src_klass, |
307 BasicType dst_type, klassOop dst_klass) { |
320 BasicType dst_type, klassOop dst_klass) { |
308 return check_argument_type_change(src_type, src_klass, dst_type, dst_klass, -1); |
321 return check_argument_type_change(src_type, src_klass, dst_type, dst_klass, -1); |
355 int decode_flags, |
368 int decode_flags, |
356 KlassHandle receiver_klass, |
369 KlassHandle receiver_klass, |
357 TRAPS); |
370 TRAPS); |
358 |
371 |
359 static bool same_basic_type_for_arguments(BasicType src, BasicType dst, |
372 static bool same_basic_type_for_arguments(BasicType src, BasicType dst, |
|
373 bool raw = false, |
360 bool for_return = false); |
374 bool for_return = false); |
361 static bool same_basic_type_for_returns(BasicType src, BasicType dst) { |
375 static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) { |
362 return same_basic_type_for_arguments(src, dst, true); |
376 return same_basic_type_for_arguments(src, dst, raw, true); |
363 } |
377 } |
364 |
378 |
365 enum { // arg_mask values |
379 enum { // arg_mask values |
366 _INSERT_NO_MASK = -1, |
380 _INSERT_NO_MASK = -1, |
367 _INSERT_REF_MASK = 0, |
381 _INSERT_REF_MASK = 0, |