91 |
91 |
92 // reference to primitive: |
92 // reference to primitive: |
93 _adapter_opt_unboxi, |
93 _adapter_opt_unboxi, |
94 _adapter_opt_unboxl, |
94 _adapter_opt_unboxl, |
95 |
95 |
96 // spreading (array length cases 0, 1, >=2) |
96 // %% Maybe tame the following with a VM_SYMBOLS_DO type macro? |
97 _adapter_opt_spread_0, |
97 |
98 _adapter_opt_spread_1, |
98 // how a blocking adapter returns (platform-dependent) |
99 _adapter_opt_spread_more, |
99 _adapter_opt_return_ref, |
|
100 _adapter_opt_return_int, |
|
101 _adapter_opt_return_long, |
|
102 _adapter_opt_return_float, |
|
103 _adapter_opt_return_double, |
|
104 _adapter_opt_return_void, |
|
105 _adapter_opt_return_S0_ref, // return ref to S=0 (last slot) |
|
106 _adapter_opt_return_S1_ref, // return ref to S=1 (2nd-to-last slot) |
|
107 _adapter_opt_return_S2_ref, |
|
108 _adapter_opt_return_S3_ref, |
|
109 _adapter_opt_return_S4_ref, |
|
110 _adapter_opt_return_S5_ref, |
|
111 _adapter_opt_return_any, // dynamically select r/i/l/f/d |
|
112 _adapter_opt_return_FIRST = _adapter_opt_return_ref, |
|
113 _adapter_opt_return_LAST = _adapter_opt_return_any, |
|
114 |
|
115 // spreading (array length cases 0, 1, ...) |
|
116 _adapter_opt_spread_0, // spread empty array to N=0 arguments |
|
117 _adapter_opt_spread_1_ref, // spread Object[] to N=1 argument |
|
118 _adapter_opt_spread_2_ref, // spread Object[] to N=2 arguments |
|
119 _adapter_opt_spread_3_ref, // spread Object[] to N=3 arguments |
|
120 _adapter_opt_spread_4_ref, // spread Object[] to N=4 arguments |
|
121 _adapter_opt_spread_5_ref, // spread Object[] to N=5 arguments |
|
122 _adapter_opt_spread_ref, // spread Object[] to N arguments |
|
123 _adapter_opt_spread_byte, // spread byte[] or boolean[] to N arguments |
|
124 _adapter_opt_spread_char, // spread char[], etc., to N arguments |
|
125 _adapter_opt_spread_short, // spread short[], etc., to N arguments |
|
126 _adapter_opt_spread_int, // spread int[], short[], etc., to N arguments |
|
127 _adapter_opt_spread_long, // spread long[] to N arguments |
|
128 _adapter_opt_spread_float, // spread float[] to N arguments |
|
129 _adapter_opt_spread_double, // spread double[] to N arguments |
|
130 _adapter_opt_spread_FIRST = _adapter_opt_spread_0, |
|
131 _adapter_opt_spread_LAST = _adapter_opt_spread_double, |
|
132 |
|
133 // blocking filter/collect conversions |
|
134 // These collect N arguments and replace them (at slot S) by a return value |
|
135 // which is passed to the final target, along with the unaffected arguments. |
|
136 // collect_{N}_{T} collects N arguments at any position into a T value |
|
137 // collect_{N}_S{S}_{T} collects N arguments at slot S into a T value |
|
138 // collect_{T} collects any number of arguments at any position |
|
139 // filter_S{S}_{T} is the same as collect_1_S{S}_{T} (a unary collection) |
|
140 // (collect_2 is also usable as a filter, with long or double arguments) |
|
141 _adapter_opt_collect_ref, // combine N arguments, replace with a reference |
|
142 _adapter_opt_collect_int, // combine N arguments, replace with an int, short, etc. |
|
143 _adapter_opt_collect_long, // combine N arguments, replace with a long |
|
144 _adapter_opt_collect_float, // combine N arguments, replace with a float |
|
145 _adapter_opt_collect_double, // combine N arguments, replace with a double |
|
146 _adapter_opt_collect_void, // combine N arguments, replace with nothing |
|
147 // if there is a small fixed number to push, do so without a loop: |
|
148 _adapter_opt_collect_0_ref, // collect N=0 arguments, insert a reference |
|
149 _adapter_opt_collect_1_ref, // collect N=1 argument, replace with a reference |
|
150 _adapter_opt_collect_2_ref, // combine N=2 arguments, replace with a reference |
|
151 _adapter_opt_collect_3_ref, // combine N=3 arguments, replace with a reference |
|
152 _adapter_opt_collect_4_ref, // combine N=4 arguments, replace with a reference |
|
153 _adapter_opt_collect_5_ref, // combine N=5 arguments, replace with a reference |
|
154 // filters are an important special case because they never move arguments: |
|
155 _adapter_opt_filter_S0_ref, // filter N=1 argument at S=0, replace with a reference |
|
156 _adapter_opt_filter_S1_ref, // filter N=1 argument at S=1, replace with a reference |
|
157 _adapter_opt_filter_S2_ref, // filter N=1 argument at S=2, replace with a reference |
|
158 _adapter_opt_filter_S3_ref, // filter N=1 argument at S=3, replace with a reference |
|
159 _adapter_opt_filter_S4_ref, // filter N=1 argument at S=4, replace with a reference |
|
160 _adapter_opt_filter_S5_ref, // filter N=1 argument at S=5, replace with a reference |
|
161 // these move arguments, but they are important for boxing |
|
162 _adapter_opt_collect_2_S0_ref, // combine last N=2 arguments, replace with a reference |
|
163 _adapter_opt_collect_2_S1_ref, // combine N=2 arguments at S=1, replace with a reference |
|
164 _adapter_opt_collect_2_S2_ref, // combine N=2 arguments at S=2, replace with a reference |
|
165 _adapter_opt_collect_2_S3_ref, // combine N=2 arguments at S=3, replace with a reference |
|
166 _adapter_opt_collect_2_S4_ref, // combine N=2 arguments at S=4, replace with a reference |
|
167 _adapter_opt_collect_2_S5_ref, // combine N=2 arguments at S=5, replace with a reference |
|
168 _adapter_opt_collect_FIRST = _adapter_opt_collect_ref, |
|
169 _adapter_opt_collect_LAST = _adapter_opt_collect_2_S5_ref, |
|
170 |
|
171 // blocking folding conversions |
|
172 // these are like collects, but retain all the N arguments for the final target |
|
173 //_adapter_opt_fold_0_ref, // same as _adapter_opt_collect_0_ref |
|
174 // fold_{N}_{T} processes N arguments at any position into a T value, which it inserts |
|
175 // fold_{T} processes any number of arguments at any position |
|
176 _adapter_opt_fold_ref, // process N arguments, prepend a reference |
|
177 _adapter_opt_fold_int, // process N arguments, prepend an int, short, etc. |
|
178 _adapter_opt_fold_long, // process N arguments, prepend a long |
|
179 _adapter_opt_fold_float, // process N arguments, prepend a float |
|
180 _adapter_opt_fold_double, // process N arguments, prepend a double |
|
181 _adapter_opt_fold_void, // process N arguments, but leave the list unchanged |
|
182 _adapter_opt_fold_1_ref, // process N=1 argument, prepend a reference |
|
183 _adapter_opt_fold_2_ref, // process N=2 arguments, prepend a reference |
|
184 _adapter_opt_fold_3_ref, // process N=3 arguments, prepend a reference |
|
185 _adapter_opt_fold_4_ref, // process N=4 arguments, prepend a reference |
|
186 _adapter_opt_fold_5_ref, // process N=5 arguments, prepend a reference |
|
187 _adapter_opt_fold_FIRST = _adapter_opt_fold_ref, |
|
188 _adapter_opt_fold_LAST = _adapter_opt_fold_5_ref, |
100 |
189 |
101 _EK_LIMIT, |
190 _EK_LIMIT, |
102 _EK_FIRST = 0 |
191 _EK_FIRST = 0 |
103 }; |
192 }; |
104 |
193 |
145 assert(_entries[ek] == NULL, "no double initialization"); |
236 assert(_entries[ek] == NULL, "no double initialization"); |
146 _entries[ek] = me; |
237 _entries[ek] = me; |
147 } |
238 } |
148 |
239 |
149 // Some adapter helper functions. |
240 // Some adapter helper functions. |
150 static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) { |
241 static EntryKind ek_original_kind(EntryKind ek) { |
151 switch (ek) { |
242 if (ek <= _adapter_mh_last) return ek; |
152 case _bound_int_mh : // fall-thru |
243 switch (ek) { |
153 case _bound_int_direct_mh : arg_type = T_INT; arg_mask = _INSERT_INT_MASK; break; |
244 case _adapter_opt_swap_1: |
154 case _bound_long_mh : // fall-thru |
245 case _adapter_opt_swap_2: |
155 case _bound_long_direct_mh: arg_type = T_LONG; arg_mask = _INSERT_LONG_MASK; break; |
246 return _adapter_swap_args; |
156 case _bound_ref_mh : // fall-thru |
247 case _adapter_opt_rot_1_up: |
157 case _bound_ref_direct_mh : arg_type = T_OBJECT; arg_mask = _INSERT_REF_MASK; break; |
248 case _adapter_opt_rot_1_down: |
158 default: ShouldNotReachHere(); |
249 case _adapter_opt_rot_2_up: |
159 } |
250 case _adapter_opt_rot_2_down: |
160 arg_slots = type2size[arg_type]; |
251 return _adapter_rot_args; |
161 } |
252 case _adapter_opt_i2i: |
162 |
253 case _adapter_opt_l2i: |
163 static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) { |
254 case _adapter_opt_d2f: |
164 int swap_slots = 0; |
255 case _adapter_opt_i2l: |
165 switch (ek) { |
256 case _adapter_opt_f2d: |
166 case _adapter_opt_swap_1: swap_slots = 1; rotate = 0; break; |
257 return _adapter_prim_to_prim; |
167 case _adapter_opt_swap_2: swap_slots = 2; rotate = 0; break; |
258 case _adapter_opt_unboxi: |
168 case _adapter_opt_rot_1_up: swap_slots = 1; rotate = 1; break; |
259 case _adapter_opt_unboxl: |
169 case _adapter_opt_rot_1_down: swap_slots = 1; rotate = -1; break; |
260 return _adapter_ref_to_prim; |
170 case _adapter_opt_rot_2_up: swap_slots = 2; rotate = 1; break; |
261 } |
171 case _adapter_opt_rot_2_down: swap_slots = 2; rotate = -1; break; |
262 if (ek >= _adapter_opt_spread_FIRST && ek <= _adapter_opt_spread_LAST) |
172 default: ShouldNotReachHere(); |
263 return _adapter_spread_args; |
173 } |
264 if (ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST) |
174 // Return the size of the stack slots to move in bytes. |
265 return _adapter_collect_args; |
175 swap_bytes = swap_slots * Interpreter::stackElementSize; |
266 if (ek >= _adapter_opt_fold_FIRST && ek <= _adapter_opt_fold_LAST) |
176 } |
267 return _adapter_fold_args; |
177 |
268 if (ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST) |
178 static int get_ek_adapter_opt_spread_info(EntryKind ek) { |
269 return _adapter_opt_return_any; |
179 switch (ek) { |
270 assert(false, "oob"); |
180 case _adapter_opt_spread_0: return 0; |
271 return _EK_LIMIT; |
181 case _adapter_opt_spread_1: return 1; |
272 } |
182 default : return -1; |
273 |
|
274 static bool ek_supported(MethodHandles::EntryKind ek); |
|
275 |
|
276 static BasicType ek_bound_mh_arg_type(EntryKind ek) { |
|
277 switch (ek) { |
|
278 case _bound_int_mh : // fall-thru |
|
279 case _bound_int_direct_mh : return T_INT; |
|
280 case _bound_long_mh : // fall-thru |
|
281 case _bound_long_direct_mh : return T_LONG; |
|
282 default : return T_OBJECT; |
|
283 } |
|
284 } |
|
285 |
|
286 static int ek_adapter_opt_swap_slots(EntryKind ek) { |
|
287 switch (ek) { |
|
288 case _adapter_opt_swap_1 : return 1; |
|
289 case _adapter_opt_swap_2 : return 2; |
|
290 case _adapter_opt_rot_1_up : return 1; |
|
291 case _adapter_opt_rot_1_down : return 1; |
|
292 case _adapter_opt_rot_2_up : return 2; |
|
293 case _adapter_opt_rot_2_down : return 2; |
|
294 default : ShouldNotReachHere(); return -1; |
|
295 } |
|
296 } |
|
297 |
|
298 static int ek_adapter_opt_swap_mode(EntryKind ek) { |
|
299 switch (ek) { |
|
300 case _adapter_opt_swap_1 : return 0; |
|
301 case _adapter_opt_swap_2 : return 0; |
|
302 case _adapter_opt_rot_1_up : return 1; |
|
303 case _adapter_opt_rot_1_down : return -1; |
|
304 case _adapter_opt_rot_2_up : return 1; |
|
305 case _adapter_opt_rot_2_down : return -1; |
|
306 default : ShouldNotReachHere(); return 0; |
|
307 } |
|
308 } |
|
309 |
|
310 static int ek_adapter_opt_collect_count(EntryKind ek) { |
|
311 assert(ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST || |
|
312 ek >= _adapter_opt_fold_FIRST && ek <= _adapter_opt_fold_LAST, ""); |
|
313 switch (ek) { |
|
314 case _adapter_opt_collect_0_ref : return 0; |
|
315 case _adapter_opt_filter_S0_ref : |
|
316 case _adapter_opt_filter_S1_ref : |
|
317 case _adapter_opt_filter_S2_ref : |
|
318 case _adapter_opt_filter_S3_ref : |
|
319 case _adapter_opt_filter_S4_ref : |
|
320 case _adapter_opt_filter_S5_ref : |
|
321 case _adapter_opt_fold_1_ref : |
|
322 case _adapter_opt_collect_1_ref : return 1; |
|
323 case _adapter_opt_collect_2_S0_ref : |
|
324 case _adapter_opt_collect_2_S1_ref : |
|
325 case _adapter_opt_collect_2_S2_ref : |
|
326 case _adapter_opt_collect_2_S3_ref : |
|
327 case _adapter_opt_collect_2_S4_ref : |
|
328 case _adapter_opt_collect_2_S5_ref : |
|
329 case _adapter_opt_fold_2_ref : |
|
330 case _adapter_opt_collect_2_ref : return 2; |
|
331 case _adapter_opt_fold_3_ref : |
|
332 case _adapter_opt_collect_3_ref : return 3; |
|
333 case _adapter_opt_fold_4_ref : |
|
334 case _adapter_opt_collect_4_ref : return 4; |
|
335 case _adapter_opt_fold_5_ref : |
|
336 case _adapter_opt_collect_5_ref : return 5; |
|
337 default : return -1; // sentinel value for "variable" |
|
338 } |
|
339 } |
|
340 |
|
341 static int ek_adapter_opt_collect_slot(EntryKind ek) { |
|
342 assert(ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST || |
|
343 ek >= _adapter_opt_fold_FIRST && ek <= _adapter_opt_fold_LAST, ""); |
|
344 switch (ek) { |
|
345 case _adapter_opt_collect_2_S0_ref : |
|
346 case _adapter_opt_filter_S0_ref : return 0; |
|
347 case _adapter_opt_collect_2_S1_ref : |
|
348 case _adapter_opt_filter_S1_ref : return 1; |
|
349 case _adapter_opt_collect_2_S2_ref : |
|
350 case _adapter_opt_filter_S2_ref : return 2; |
|
351 case _adapter_opt_collect_2_S3_ref : |
|
352 case _adapter_opt_filter_S3_ref : return 3; |
|
353 case _adapter_opt_collect_2_S4_ref : |
|
354 case _adapter_opt_filter_S4_ref : return 4; |
|
355 case _adapter_opt_collect_2_S5_ref : |
|
356 case _adapter_opt_filter_S5_ref : return 5; |
|
357 default : return -1; // sentinel value for "variable" |
|
358 } |
|
359 } |
|
360 |
|
361 static BasicType ek_adapter_opt_collect_type(EntryKind ek) { |
|
362 assert(ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST || |
|
363 ek >= _adapter_opt_fold_FIRST && ek <= _adapter_opt_fold_LAST, ""); |
|
364 switch (ek) { |
|
365 case _adapter_opt_fold_int : |
|
366 case _adapter_opt_collect_int : return T_INT; |
|
367 case _adapter_opt_fold_long : |
|
368 case _adapter_opt_collect_long : return T_LONG; |
|
369 case _adapter_opt_fold_float : |
|
370 case _adapter_opt_collect_float : return T_FLOAT; |
|
371 case _adapter_opt_fold_double : |
|
372 case _adapter_opt_collect_double : return T_DOUBLE; |
|
373 case _adapter_opt_fold_void : |
|
374 case _adapter_opt_collect_void : return T_VOID; |
|
375 default : return T_OBJECT; |
|
376 } |
|
377 } |
|
378 |
|
379 static int ek_adapter_opt_return_slot(EntryKind ek) { |
|
380 assert(ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST, ""); |
|
381 switch (ek) { |
|
382 case _adapter_opt_return_S0_ref : return 0; |
|
383 case _adapter_opt_return_S1_ref : return 1; |
|
384 case _adapter_opt_return_S2_ref : return 2; |
|
385 case _adapter_opt_return_S3_ref : return 3; |
|
386 case _adapter_opt_return_S4_ref : return 4; |
|
387 case _adapter_opt_return_S5_ref : return 5; |
|
388 default : return -1; // sentinel value for "variable" |
|
389 } |
|
390 } |
|
391 |
|
392 static BasicType ek_adapter_opt_return_type(EntryKind ek) { |
|
393 assert(ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST, ""); |
|
394 switch (ek) { |
|
395 case _adapter_opt_return_int : return T_INT; |
|
396 case _adapter_opt_return_long : return T_LONG; |
|
397 case _adapter_opt_return_float : return T_FLOAT; |
|
398 case _adapter_opt_return_double : return T_DOUBLE; |
|
399 case _adapter_opt_return_void : return T_VOID; |
|
400 case _adapter_opt_return_any : return T_CONFLICT; // sentinel value for "variable" |
|
401 default : return T_OBJECT; |
|
402 } |
|
403 } |
|
404 |
|
405 static int ek_adapter_opt_spread_count(EntryKind ek) { |
|
406 assert(ek >= _adapter_opt_spread_FIRST && ek <= _adapter_opt_spread_LAST, ""); |
|
407 switch (ek) { |
|
408 case _adapter_opt_spread_0 : return 0; |
|
409 case _adapter_opt_spread_1_ref : return 1; |
|
410 case _adapter_opt_spread_2_ref : return 2; |
|
411 case _adapter_opt_spread_3_ref : return 3; |
|
412 case _adapter_opt_spread_4_ref : return 4; |
|
413 case _adapter_opt_spread_5_ref : return 5; |
|
414 default : return -1; // sentinel value for "variable" |
|
415 } |
|
416 } |
|
417 |
|
418 static BasicType ek_adapter_opt_spread_type(EntryKind ek) { |
|
419 assert(ek >= _adapter_opt_spread_FIRST && ek <= _adapter_opt_spread_LAST, ""); |
|
420 switch (ek) { |
|
421 // (there is no _adapter_opt_spread_boolean; we use byte) |
|
422 case _adapter_opt_spread_byte : return T_BYTE; |
|
423 case _adapter_opt_spread_char : return T_CHAR; |
|
424 case _adapter_opt_spread_short : return T_SHORT; |
|
425 case _adapter_opt_spread_int : return T_INT; |
|
426 case _adapter_opt_spread_long : return T_LONG; |
|
427 case _adapter_opt_spread_float : return T_FLOAT; |
|
428 case _adapter_opt_spread_double : return T_DOUBLE; |
|
429 default : return T_OBJECT; |
183 } |
430 } |
184 } |
431 } |
185 |
432 |
186 static methodOop raise_exception_method() { |
433 static methodOop raise_exception_method() { |
187 oop rem = JNIHandles::resolve(_raise_exception_method); |
434 oop rem = JNIHandles::resolve(_raise_exception_method); |
446 bool for_return = false); |
703 bool for_return = false); |
447 static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) { |
704 static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) { |
448 return same_basic_type_for_arguments(src, dst, raw, true); |
705 return same_basic_type_for_arguments(src, dst, raw, true); |
449 } |
706 } |
450 |
707 |
451 enum { // arg_mask values |
708 static Symbol* convert_to_signature(oop type_str, bool polymorphic, TRAPS); |
|
709 |
|
710 #ifdef TARGET_ARCH_x86 |
|
711 # include "methodHandles_x86.hpp" |
|
712 #endif |
|
713 #ifdef TARGET_ARCH_sparc |
|
714 #define TARGET_ARCH_NYI_6939861 1 //FIXME |
|
715 //# include "methodHandles_sparc.hpp" |
|
716 #endif |
|
717 #ifdef TARGET_ARCH_zero |
|
718 #define TARGET_ARCH_NYI_6939861 1 //FIXME |
|
719 //# include "methodHandles_zero.hpp" |
|
720 #endif |
|
721 #ifdef TARGET_ARCH_arm |
|
722 #define TARGET_ARCH_NYI_6939861 1 //FIXME |
|
723 //# include "methodHandles_arm.hpp" |
|
724 #endif |
|
725 #ifdef TARGET_ARCH_ppc |
|
726 #define TARGET_ARCH_NYI_6939861 1 //FIXME |
|
727 //# include "methodHandles_ppc.hpp" |
|
728 #endif |
|
729 |
|
730 #ifdef TARGET_ARCH_NYI_6939861 |
|
731 // Here are some backward compatible declarations until the 6939861 ports are updated. |
|
732 #define _adapter_flyby (_EK_LIMIT + 10) |
|
733 #define _adapter_ricochet (_EK_LIMIT + 11) |
|
734 #define _adapter_opt_spread_1 _adapter_opt_spread_1_ref |
|
735 #define _adapter_opt_spread_more _adapter_opt_spread_ref |
|
736 enum { |
452 _INSERT_NO_MASK = -1, |
737 _INSERT_NO_MASK = -1, |
453 _INSERT_REF_MASK = 0, |
738 _INSERT_REF_MASK = 0, |
454 _INSERT_INT_MASK = 1, |
739 _INSERT_INT_MASK = 1, |
455 _INSERT_LONG_MASK = 3 |
740 _INSERT_LONG_MASK = 3 |
456 }; |
741 }; |
|
742 static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) { |
|
743 arg_type = ek_bound_mh_arg_type(ek); |
|
744 arg_mask = 0; |
|
745 arg_slots = type2size[arg_type];; |
|
746 } |
|
747 static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) { |
|
748 int swap_slots = ek_adapter_opt_swap_slots(ek); |
|
749 rotate = ek_adapter_opt_swap_mode(ek); |
|
750 swap_bytes = swap_slots * Interpreter::stackElementSize; |
|
751 } |
|
752 static int get_ek_adapter_opt_spread_info(EntryKind ek) { |
|
753 return ek_adapter_opt_spread_count(ek); |
|
754 } |
|
755 |
457 static void insert_arg_slots(MacroAssembler* _masm, |
756 static void insert_arg_slots(MacroAssembler* _masm, |
458 RegisterOrConstant arg_slots, |
757 RegisterOrConstant arg_slots, |
459 int arg_mask, |
758 int arg_mask, |
460 Register argslot_reg, |
759 Register argslot_reg, |
461 Register temp_reg, Register temp2_reg, Register temp3_reg = noreg); |
760 Register temp_reg, Register temp2_reg, Register temp3_reg = noreg); |