Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 1304:76c1d7d13ec5
6932091: JSR 292 x86 code cleanup
Summary: Some code cleanups found during the JSR 292 SPARC port.
Reviewed-by: kvn, never
author | twisti |
---|---|
date | Thu, 18 Mar 2010 09:56:51 +0100 |
parents | 51db1e4b379d |
children | 4a9cc99938e3 |
comparison
equal
deleted
inserted
replaced
1303:c047da02984c | 1304:76c1d7d13ec5 |
---|---|
58 | 58 |
59 return me; | 59 return me; |
60 } | 60 } |
61 | 61 |
62 #ifdef ASSERT | 62 #ifdef ASSERT |
63 static void verify_argslot(MacroAssembler* _masm, Register rax_argslot, | 63 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, |
64 const char* error_message) { | 64 const char* error_message) { |
65 // Verify that argslot lies within (rsp, rbp]. | 65 // Verify that argslot lies within (rsp, rbp]. |
66 Label L_ok, L_bad; | 66 Label L_ok, L_bad; |
67 __ cmpptr(rax_argslot, rbp); | 67 __ cmpptr(argslot_reg, rbp); |
68 __ jccb(Assembler::above, L_bad); | 68 __ jccb(Assembler::above, L_bad); |
69 __ cmpptr(rsp, rax_argslot); | 69 __ cmpptr(rsp, argslot_reg); |
70 __ jccb(Assembler::below, L_ok); | 70 __ jccb(Assembler::below, L_ok); |
71 __ bind(L_bad); | 71 __ bind(L_bad); |
72 __ stop(error_message); | 72 __ stop(error_message); |
73 __ bind(L_ok); | 73 __ bind(L_ok); |
74 } | 74 } |
176 __ jccb(Assembler::less, loop); | 176 __ jccb(Assembler::less, loop); |
177 } | 177 } |
178 | 178 |
179 // Now move the argslot down, to point to the opened-up space. | 179 // Now move the argslot down, to point to the opened-up space. |
180 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); | 180 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); |
181 | |
182 if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) { | |
183 // The caller has specified a bitmask of tags to put into the opened space. | |
184 // This only works when the arg_slots value is an assembly-time constant. | |
185 int constant_arg_slots = arg_slots.as_constant() / stack_move_unit(); | |
186 int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); | |
187 for (int slot = 0; slot < constant_arg_slots; slot++) { | |
188 BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT); | |
189 int slot_offset = Interpreter::stackElementSize() * slot; | |
190 Address tag_addr(rax_argslot, slot_offset + tag_offset); | |
191 __ movptr(tag_addr, frame::tag_for_basic_type(slot_type)); | |
192 } | |
193 // Note that the new argument slots are tagged properly but contain | |
194 // garbage at this point. The value portions must be initialized | |
195 // by the caller. (Especially references!) | |
196 } | |
197 } | 181 } |
198 | 182 |
199 // Helper to remove argument slots from the stack. | 183 // Helper to remove argument slots from the stack. |
200 // arg_slots must be a multiple of stack_move_unit() and >= 0 | 184 // arg_slots must be a multiple of stack_move_unit() and >= 0 |
201 void MethodHandles::remove_arg_slots(MacroAssembler* _masm, | 185 void MethodHandles::remove_arg_slots(MacroAssembler* _masm, |
204 Register rbx_temp, Register rdx_temp) { | 188 Register rbx_temp, Register rdx_temp) { |
205 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, | 189 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, |
206 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); | 190 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); |
207 | 191 |
208 #ifdef ASSERT | 192 #ifdef ASSERT |
209 { | 193 // Verify that [argslot..argslot+size) lies within (rsp, rbp). |
210 // Verify that [argslot..argslot+size) lies within (rsp, rbp). | 194 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); |
211 Label L_ok, L_bad; | 195 verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame"); |
212 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); | |
213 __ cmpptr(rbx_temp, rbp); | |
214 __ jccb(Assembler::above, L_bad); | |
215 __ cmpptr(rsp, rax_argslot); | |
216 __ jccb(Assembler::below, L_ok); | |
217 __ bind(L_bad); | |
218 __ stop("deleted argument(s) must fall within current frame"); | |
219 __ bind(L_ok); | |
220 } | |
221 if (arg_slots.is_register()) { | 196 if (arg_slots.is_register()) { |
222 Label L_ok, L_bad; | 197 Label L_ok, L_bad; |
223 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); | 198 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); |
224 __ jccb(Assembler::less, L_bad); | 199 __ jccb(Assembler::less, L_bad); |
225 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); | 200 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); |
319 Address rcx_amh_vmargslot( rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() ); | 294 Address rcx_amh_vmargslot( rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() ); |
320 Address rcx_amh_argument( rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() ); | 295 Address rcx_amh_argument( rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() ); |
321 Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() ); | 296 Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() ); |
322 Address vmarg; // __ argument_address(vmargslot) | 297 Address vmarg; // __ argument_address(vmargslot) |
323 | 298 |
324 int tag_offset = -1; | |
325 if (TaggedStackInterpreter) { | |
326 tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); | |
327 assert(tag_offset = wordSize, "stack grows as expected"); | |
328 } | |
329 | |
330 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); | 299 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); |
331 | 300 |
332 if (have_entry(ek)) { | 301 if (have_entry(ek)) { |
333 __ nop(); // empty stubs make SG sick | 302 __ nop(); // empty stubs make SG sick |
334 return; | 303 return; |
370 __ pop(rdi_pc); // caller PC | 339 __ pop(rdi_pc); // caller PC |
371 | 340 |
372 __ mov(rsp, rsi); // cut the stack back to where the caller started | 341 __ mov(rsp, rsi); // cut the stack back to where the caller started |
373 | 342 |
374 // Repush the arguments as if coming from the interpreter. | 343 // Repush the arguments as if coming from the interpreter. |
375 if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT)); | |
376 __ push(rdx_code); | 344 __ push(rdx_code); |
377 if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); | |
378 __ push(rcx_fail); | 345 __ push(rcx_fail); |
379 if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); | |
380 __ push(rax_want); | 346 __ push(rax_want); |
381 | 347 |
382 Register rbx_method = rbx_temp; | 348 Register rbx_method = rbx_temp; |
383 Label no_method; | 349 Label no_method; |
384 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method | 350 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method |
395 | 361 |
396 // If we get here, the Java runtime did not do its job of creating the exception. | 362 // If we get here, the Java runtime did not do its job of creating the exception. |
397 // Do something that is at least causes a valid throw from the interpreter. | 363 // Do something that is at least causes a valid throw from the interpreter. |
398 __ bind(no_method); | 364 __ bind(no_method); |
399 __ pop(rax_want); | 365 __ pop(rax_want); |
400 if (TaggedStackInterpreter) __ pop(rcx_fail); | |
401 __ pop(rcx_fail); | 366 __ pop(rcx_fail); |
402 __ push(rax_want); | 367 __ push(rax_want); |
403 __ push(rcx_fail); | 368 __ push(rcx_fail); |
404 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); | 369 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); |
405 } | 370 } |
508 case _bound_ref_direct_mh: | 473 case _bound_ref_direct_mh: |
509 case _bound_int_direct_mh: | 474 case _bound_int_direct_mh: |
510 case _bound_long_direct_mh: | 475 case _bound_long_direct_mh: |
511 { | 476 { |
512 bool direct_to_method = (ek >= _bound_ref_direct_mh); | 477 bool direct_to_method = (ek >= _bound_ref_direct_mh); |
513 BasicType arg_type = T_ILLEGAL; | 478 BasicType arg_type = T_ILLEGAL; |
514 if (ek == _bound_long_mh || ek == _bound_long_direct_mh) { | 479 int arg_mask = _INSERT_NO_MASK; |
515 arg_type = T_LONG; | 480 int arg_slots = -1; |
516 } else if (ek == _bound_int_mh || ek == _bound_int_direct_mh) { | 481 get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots); |
517 arg_type = T_INT; | |
518 } else { | |
519 assert(ek == _bound_ref_mh || ek == _bound_ref_direct_mh, "must be ref"); | |
520 arg_type = T_OBJECT; | |
521 } | |
522 int arg_slots = type2size[arg_type]; | |
523 int arg_mask = (arg_type == T_OBJECT ? _INSERT_REF_MASK : | |
524 arg_slots == 1 ? _INSERT_INT_MASK : _INSERT_LONG_MASK); | |
525 | 482 |
526 // make room for the new argument: | 483 // make room for the new argument: |
527 __ movl(rax_argslot, rcx_bmh_vmargslot); | 484 __ movl(rax_argslot, rcx_bmh_vmargslot); |
528 __ lea(rax_argslot, __ argument_address(rax_argslot)); | 485 __ lea(rax_argslot, __ argument_address(rax_argslot)); |
529 insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, | 486 insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, |
658 // the low bits will be correct, but the high bits may need cleaning. | 615 // the low bits will be correct, but the high bits may need cleaning. |
659 // The vminfo will guide us to clean those bits. | 616 // The vminfo will guide us to clean those bits. |
660 } | 617 } |
661 break; | 618 break; |
662 default: | 619 default: |
663 assert(false, ""); | 620 ShouldNotReachHere(); |
664 } | 621 } |
665 goto finish_int_conversion; | 622 |
666 } | 623 // Do the requested conversion and store the value. |
667 | |
668 finish_int_conversion: | |
669 { | |
670 Register rbx_vminfo = rbx_temp; | 624 Register rbx_vminfo = rbx_temp; |
671 __ movl(rbx_vminfo, rcx_amh_conversion); | 625 __ movl(rbx_vminfo, rcx_amh_conversion); |
672 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); | 626 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); |
673 | 627 |
674 // get the new MH: | 628 // get the new MH: |
690 __ bind(zero_extend); | 644 __ bind(zero_extend); |
691 // this is taken for int->char | 645 // this is taken for int->char |
692 __ shrl(rdx_temp /*, rcx*/); | 646 __ shrl(rdx_temp /*, rcx*/); |
693 | 647 |
694 __ bind(done); | 648 __ bind(done); |
695 __ movl(vmarg, rdx_temp); | 649 __ movl(vmarg, rdx_temp); // Store the value. |
696 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv | 650 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv |
697 | 651 |
698 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); | 652 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
699 } | 653 } |
700 break; | 654 break; |
742 __ movl(vmarg2, rdx_temp); | 696 __ movl(vmarg2, rdx_temp); |
743 #endif | 697 #endif |
744 } | 698 } |
745 break; | 699 break; |
746 default: | 700 default: |
747 assert(false, ""); | 701 ShouldNotReachHere(); |
748 } | 702 } |
749 | 703 |
750 __ movptr(rcx_recv, rcx_mh_vmtarget); | 704 __ movptr(rcx_recv, rcx_mh_vmtarget); |
751 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); | 705 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
752 } | 706 } |
776 } | 730 } |
777 #else //_LP64 | 731 #else //_LP64 |
778 if (ek == _adapter_opt_f2d) { | 732 if (ek == _adapter_opt_f2d) { |
779 __ fld_s(vmarg); // load float to ST0 | 733 __ fld_s(vmarg); // load float to ST0 |
780 __ fstp_s(vmarg); // store single | 734 __ fstp_s(vmarg); // store single |
781 } else if (!TaggedStackInterpreter) { | 735 } else { |
782 __ fld_d(vmarg); // load double to ST0 | 736 __ fld_d(vmarg); // load double to ST0 |
783 __ fstp_s(vmarg); // store single | |
784 } else { | |
785 Address vmarg_tag = vmarg.plus_disp(tag_offset); | |
786 Address vmarg2 = vmarg.plus_disp(Interpreter::stackElementSize()); | |
787 // vmarg2_tag does not participate in this code | |
788 Register rbx_tag = rbx_temp; | |
789 __ movl(rbx_tag, vmarg_tag); // preserve tag | |
790 __ movl(rdx_temp, vmarg2); // get second word of double | |
791 __ movl(vmarg_tag, rdx_temp); // align with first word | |
792 __ fld_d(vmarg); // load double to ST0 | |
793 __ movl(vmarg_tag, rbx_tag); // restore tag | |
794 __ fstp_s(vmarg); // store single | 737 __ fstp_s(vmarg); // store single |
795 } | 738 } |
796 #endif //_LP64 | 739 #endif //_LP64 |
797 | 740 |
798 if (ek == _adapter_opt_d2f) { | 741 if (ek == _adapter_opt_d2f) { |
820 case _adapter_opt_rot_1_up: | 763 case _adapter_opt_rot_1_up: |
821 case _adapter_opt_rot_1_down: | 764 case _adapter_opt_rot_1_down: |
822 case _adapter_opt_rot_2_up: | 765 case _adapter_opt_rot_2_up: |
823 case _adapter_opt_rot_2_down: | 766 case _adapter_opt_rot_2_down: |
824 { | 767 { |
825 int rotate = 0, swap_slots = 0; | 768 int swap_bytes = 0, rotate = 0; |
826 switch ((int)ek) { | 769 get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate); |
827 case _adapter_opt_swap_1: swap_slots = 1; break; | |
828 case _adapter_opt_swap_2: swap_slots = 2; break; | |
829 case _adapter_opt_rot_1_up: swap_slots = 1; rotate++; break; | |
830 case _adapter_opt_rot_1_down: swap_slots = 1; rotate--; break; | |
831 case _adapter_opt_rot_2_up: swap_slots = 2; rotate++; break; | |
832 case _adapter_opt_rot_2_down: swap_slots = 2; rotate--; break; | |
833 default: assert(false, ""); | |
834 } | |
835 | |
836 // the real size of the move must be doubled if TaggedStackInterpreter: | |
837 int swap_bytes = (int)( swap_slots * Interpreter::stackElementWords() * wordSize ); | |
838 | 770 |
839 // 'argslot' is the position of the first argument to swap | 771 // 'argslot' is the position of the first argument to swap |
840 __ movl(rax_argslot, rcx_amh_vmargslot); | 772 __ movl(rax_argslot, rcx_amh_vmargslot); |
841 __ lea(rax_argslot, __ argument_address(rax_argslot)); | 773 __ lea(rax_argslot, __ argument_address(rax_argslot)); |
842 | 774 |
1022 case _adapter_opt_spread_0: | 954 case _adapter_opt_spread_0: |
1023 case _adapter_opt_spread_1: | 955 case _adapter_opt_spread_1: |
1024 case _adapter_opt_spread_more: | 956 case _adapter_opt_spread_more: |
1025 { | 957 { |
1026 // spread an array out into a group of arguments | 958 // spread an array out into a group of arguments |
1027 int length_constant = -1; | 959 int length_constant = get_ek_adapter_opt_spread_info(ek); |
1028 switch (ek) { | |
1029 case _adapter_opt_spread_0: length_constant = 0; break; | |
1030 case _adapter_opt_spread_1: length_constant = 1; break; | |
1031 } | |
1032 | 960 |
1033 // find the address of the array argument | 961 // find the address of the array argument |
1034 __ movl(rax_argslot, rcx_amh_vmargslot); | 962 __ movl(rax_argslot, rcx_amh_vmargslot); |
1035 __ lea(rax_argslot, __ argument_address(rax_argslot)); | 963 __ lea(rax_argslot, __ argument_address(rax_argslot)); |
1036 | 964 |
1122 Label loop; | 1050 Label loop; |
1123 __ bind(loop); | 1051 __ bind(loop); |
1124 __ movptr(rbx_temp, Address(rsi_source, 0)); | 1052 __ movptr(rbx_temp, Address(rsi_source, 0)); |
1125 __ movptr(Address(rax_argslot, 0), rbx_temp); | 1053 __ movptr(Address(rax_argslot, 0), rbx_temp); |
1126 __ addptr(rsi_source, type2aelembytes(elem_type)); | 1054 __ addptr(rsi_source, type2aelembytes(elem_type)); |
1127 if (TaggedStackInterpreter) { | |
1128 __ movptr(Address(rax_argslot, tag_offset), | |
1129 frame::tag_for_basic_type(elem_type)); | |
1130 } | |
1131 __ addptr(rax_argslot, Interpreter::stackElementSize()); | 1055 __ addptr(rax_argslot, Interpreter::stackElementSize()); |
1132 __ cmpptr(rax_argslot, rdx_argslot_limit); | 1056 __ cmpptr(rax_argslot, rdx_argslot_limit); |
1133 __ jccb(Assembler::less, loop); | 1057 __ jccb(Assembler::less, loop); |
1134 } else if (length_constant == 0) { | 1058 } else if (length_constant == 0) { |
1135 __ bind(skip_array_check); | 1059 __ bind(skip_array_check); |
1139 int slot_offset = 0; | 1063 int slot_offset = 0; |
1140 for (int index = 0; index < length_constant; index++) { | 1064 for (int index = 0; index < length_constant; index++) { |
1141 __ movptr(rbx_temp, Address(rsi_array, elem_offset)); | 1065 __ movptr(rbx_temp, Address(rsi_array, elem_offset)); |
1142 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); | 1066 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); |
1143 elem_offset += type2aelembytes(elem_type); | 1067 elem_offset += type2aelembytes(elem_type); |
1144 if (TaggedStackInterpreter) { | |
1145 __ movptr(Address(rax_argslot, slot_offset + tag_offset), | |
1146 frame::tag_for_basic_type(elem_type)); | |
1147 } | |
1148 slot_offset += Interpreter::stackElementSize(); | 1068 slot_offset += Interpreter::stackElementSize(); |
1149 } | 1069 } |
1150 } | 1070 } |
1151 | 1071 |
1152 // Arguments are spread. Move to next method handle. | 1072 // Arguments are spread. Move to next method handle. |