src/share/vm/prims/methodHandles.hpp

changeset 1474
987e948ebbc8
parent 1145
e5b0439ef4ae
child 1734
9eba43136cb5
equal deleted inserted replaced
1473:71fdc5052e49 1474:987e948ebbc8
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,
111 }; 111 };
112 112
113 static bool _enabled; 113 static bool _enabled;
114 static MethodHandleEntry* _entries[_EK_LIMIT]; 114 static MethodHandleEntry* _entries[_EK_LIMIT];
115 static const char* _entry_names[_EK_LIMIT+1]; 115 static const char* _entry_names[_EK_LIMIT+1];
116 static jobject _raise_exception_method;
117
116 static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; } 118 static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; }
117 static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; } 119 static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; }
118 120
119 public: 121 public:
120 static bool have_entry(EntryKind ek) { return ek_valid(ek) && _entries[ek] != NULL; } 122 static bool have_entry(EntryKind ek) { return ek_valid(ek) && _entries[ek] != NULL; }
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,

mercurial