comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 1513:df736661d0c8

Merge
author jrose
date Tue, 11 May 2010 15:19:19 -0700
parents cd5dbf694d45
children c18cbe5936b8
comparison
equal deleted inserted replaced
1496:e8e83be27dd7 1513:df736661d0c8
125 // arg_slots must be a multiple of stack_move_unit() and <= 0 125 // arg_slots must be a multiple of stack_move_unit() and <= 0
126 void MethodHandles::insert_arg_slots(MacroAssembler* _masm, 126 void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
127 RegisterOrConstant arg_slots, 127 RegisterOrConstant arg_slots,
128 int arg_mask, 128 int arg_mask,
129 Register rax_argslot, 129 Register rax_argslot,
130 Register rbx_temp, Register rdx_temp) { 130 Register rbx_temp, Register rdx_temp, Register temp3_reg) {
131 assert(temp3_reg == noreg, "temp3 not required");
131 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, 132 assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
132 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); 133 (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
133 134
134 #ifdef ASSERT 135 #ifdef ASSERT
135 verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame"); 136 verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
183 // Helper to remove argument slots from the stack. 184 // Helper to remove argument slots from the stack.
184 // arg_slots must be a multiple of stack_move_unit() and >= 0 185 // arg_slots must be a multiple of stack_move_unit() and >= 0
185 void MethodHandles::remove_arg_slots(MacroAssembler* _masm, 186 void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
186 RegisterOrConstant arg_slots, 187 RegisterOrConstant arg_slots,
187 Register rax_argslot, 188 Register rax_argslot,
188 Register rbx_temp, Register rdx_temp) { 189 Register rbx_temp, Register rdx_temp, Register temp3_reg) {
190 assert(temp3_reg == noreg, "temp3 not required");
189 assert_different_registers(rax_argslot, rbx_temp, rdx_temp, 191 assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
190 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); 192 (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
191 193
192 #ifdef ASSERT 194 #ifdef ASSERT
193 // Verify that [argslot..argslot+size) lies within (rsp, rbp). 195 // Verify that [argslot..argslot+size) lies within (rsp, rbp).
258 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp); 260 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
259 if (Verbose) print_method_handle(mh); 261 if (Verbose) print_method_handle(mh);
260 } 262 }
261 #endif //PRODUCT 263 #endif //PRODUCT
262 264
265 // which conversion op types are implemented here?
266 int MethodHandles::adapter_conversion_ops_supported_mask() {
267 return ((1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY)
268 |(1<<sun_dyn_AdapterMethodHandle::OP_RETYPE_RAW)
269 |(1<<sun_dyn_AdapterMethodHandle::OP_CHECK_CAST)
270 |(1<<sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM)
271 |(1<<sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM)
272 |(1<<sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS)
273 |(1<<sun_dyn_AdapterMethodHandle::OP_ROT_ARGS)
274 |(1<<sun_dyn_AdapterMethodHandle::OP_DUP_ARGS)
275 |(1<<sun_dyn_AdapterMethodHandle::OP_DROP_ARGS)
276 //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
277 );
278 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
279 }
280
263 // Generate an "entry" field for a method handle. 281 // Generate an "entry" field for a method handle.
264 // This determines how the method handle will respond to calls. 282 // This determines how the method handle will respond to calls.
265 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { 283 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
266 // Here is the register state during an interpreted call, 284 // Here is the register state during an interpreted call,
267 // as set up by generate_method_handle_interpreter_entry(): 285 // as set up by generate_method_handle_interpreter_entry():
496 type2aelembytes(arg_type), is_signed_subword_type(arg_type)); 514 type2aelembytes(arg_type), is_signed_subword_type(arg_type));
497 __ movptr(Address(rax_argslot, 0), rdx_temp); 515 __ movptr(Address(rax_argslot, 0), rdx_temp);
498 #ifndef _LP64 516 #ifndef _LP64
499 if (arg_slots == 2) { 517 if (arg_slots == 2) {
500 __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize)); 518 __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize));
501 __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rdx_temp); 519 __ movl(Address(rax_argslot, Interpreter::stackElementSize), rdx_temp);
502 } 520 }
503 #endif //_LP64 521 #endif //_LP64
504 } 522 }
505 523
506 if (direct_to_method) { 524 if (direct_to_method) {
592 { 610 {
593 // just delete the extra slot; on a little-endian machine we keep the first 611 // just delete the extra slot; on a little-endian machine we keep the first
594 __ lea(rax_argslot, __ argument_address(rax_argslot, 1)); 612 __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
595 remove_arg_slots(_masm, -stack_move_unit(), 613 remove_arg_slots(_masm, -stack_move_unit(),
596 rax_argslot, rbx_temp, rdx_temp); 614 rax_argslot, rbx_temp, rdx_temp);
597 vmarg = Address(rax_argslot, -Interpreter::stackElementSize()); 615 vmarg = Address(rax_argslot, -Interpreter::stackElementSize);
598 __ movl(rdx_temp, vmarg); 616 __ movl(rdx_temp, vmarg);
599 } 617 }
600 break; 618 break;
601 case _adapter_opt_unboxi: 619 case _adapter_opt_unboxi:
602 { 620 {
661 679
662 // on a little-endian machine we keep the first slot and add another after 680 // on a little-endian machine we keep the first slot and add another after
663 __ lea(rax_argslot, __ argument_address(rax_argslot, 1)); 681 __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
664 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK, 682 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK,
665 rax_argslot, rbx_temp, rdx_temp); 683 rax_argslot, rbx_temp, rdx_temp);
666 Address vmarg1(rax_argslot, -Interpreter::stackElementSize()); 684 Address vmarg1(rax_argslot, -Interpreter::stackElementSize);
667 Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize()); 685 Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize);
668 686
669 switch (ek) { 687 switch (ek) {
670 case _adapter_opt_i2l: 688 case _adapter_opt_i2l:
671 { 689 {
672 #ifdef _LP64 690 #ifdef _LP64
714 __ lea(rax_argslot, __ argument_address(rax_argslot, 1)); 732 __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
715 if (ek == _adapter_opt_f2d) { 733 if (ek == _adapter_opt_f2d) {
716 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK, 734 insert_arg_slots(_masm, stack_move_unit(), _INSERT_INT_MASK,
717 rax_argslot, rbx_temp, rdx_temp); 735 rax_argslot, rbx_temp, rdx_temp);
718 } 736 }
719 Address vmarg(rax_argslot, -Interpreter::stackElementSize()); 737 Address vmarg(rax_argslot, -Interpreter::stackElementSize);
720 738
721 #ifdef _LP64 739 #ifdef _LP64
722 if (ek == _adapter_opt_f2d) { 740 if (ek == _adapter_opt_f2d) {
723 __ movflt(xmm0, vmarg); 741 __ movflt(xmm0, vmarg);
724 __ cvtss2sd(xmm0, xmm0); 742 __ cvtss2sd(xmm0, xmm0);
1012 Register rdx_argslot_limit = rdx_temp; 1030 Register rdx_argslot_limit = rdx_temp;
1013 1031
1014 // Array length checks out. Now insert any required stack slots. 1032 // Array length checks out. Now insert any required stack slots.
1015 if (length_constant == -1) { 1033 if (length_constant == -1) {
1016 // Form a pointer to the end of the affected region. 1034 // Form a pointer to the end of the affected region.
1017 __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize())); 1035 __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize));
1018 // 'stack_move' is negative number of words to insert 1036 // 'stack_move' is negative number of words to insert
1019 Register rdi_stack_move = rdi; 1037 Register rdi_stack_move = rdi;
1020 __ movl2ptr(rdi_stack_move, rcx_amh_conversion); 1038 __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
1021 __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT); 1039 __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
1022 Register rsi_temp = rsi_array; // spill this 1040 Register rsi_temp = rsi_array; // spill this
1050 Label loop; 1068 Label loop;
1051 __ bind(loop); 1069 __ bind(loop);
1052 __ movptr(rbx_temp, Address(rsi_source, 0)); 1070 __ movptr(rbx_temp, Address(rsi_source, 0));
1053 __ movptr(Address(rax_argslot, 0), rbx_temp); 1071 __ movptr(Address(rax_argslot, 0), rbx_temp);
1054 __ addptr(rsi_source, type2aelembytes(elem_type)); 1072 __ addptr(rsi_source, type2aelembytes(elem_type));
1055 __ addptr(rax_argslot, Interpreter::stackElementSize()); 1073 __ addptr(rax_argslot, Interpreter::stackElementSize);
1056 __ cmpptr(rax_argslot, rdx_argslot_limit); 1074 __ cmpptr(rax_argslot, rdx_argslot_limit);
1057 __ jccb(Assembler::less, loop); 1075 __ jccb(Assembler::less, loop);
1058 } else if (length_constant == 0) { 1076 } else if (length_constant == 0) {
1059 __ bind(skip_array_check); 1077 __ bind(skip_array_check);
1060 // nothing to copy 1078 // nothing to copy
1063 int slot_offset = 0; 1081 int slot_offset = 0;
1064 for (int index = 0; index < length_constant; index++) { 1082 for (int index = 0; index < length_constant; index++) {
1065 __ movptr(rbx_temp, Address(rsi_array, elem_offset)); 1083 __ movptr(rbx_temp, Address(rsi_array, elem_offset));
1066 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); 1084 __ movptr(Address(rax_argslot, slot_offset), rbx_temp);
1067 elem_offset += type2aelembytes(elem_type); 1085 elem_offset += type2aelembytes(elem_type);
1068 slot_offset += Interpreter::stackElementSize(); 1086 slot_offset += Interpreter::stackElementSize;
1069 } 1087 }
1070 } 1088 }
1071 1089
1072 // Arguments are spread. Move to next method handle. 1090 // Arguments are spread. Move to next method handle.
1073 UNPUSH_RSI_RDI; 1091 UNPUSH_RSI_RDI;