comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 1135:e66fd840cb6b

6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164) Summary: During the work for 6829187 we have fixed a number of basic bugs which are logically grouped with 6815692 and 6858164 but which must be reviewed and pushed separately. Reviewed-by: kvn, never
author twisti
date Mon, 04 Jan 2010 18:38:08 +0100
parents aa62b9388fce
children 855c5171834c
comparison
equal deleted inserted replaced
1134:0910903272e5 1135:e66fd840cb6b
63 static void verify_argslot(MacroAssembler* _masm, Register rax_argslot, 63 static void verify_argslot(MacroAssembler* _masm, Register rax_argslot,
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(rax_argslot, rbp);
68 __ jcc(Assembler::above, L_bad); 68 __ jccb(Assembler::above, L_bad);
69 __ cmpptr(rsp, rax_argslot); 69 __ cmpptr(rsp, rax_argslot);
70 __ jcc(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 }
75 #endif 75 #endif
134 #ifdef ASSERT 134 #ifdef ASSERT
135 verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame"); 135 verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
136 if (arg_slots.is_register()) { 136 if (arg_slots.is_register()) {
137 Label L_ok, L_bad; 137 Label L_ok, L_bad;
138 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); 138 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
139 __ jcc(Assembler::greater, L_bad); 139 __ jccb(Assembler::greater, L_bad);
140 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); 140 __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
141 __ jcc(Assembler::zero, L_ok); 141 __ jccb(Assembler::zero, L_ok);
142 __ bind(L_bad); 142 __ bind(L_bad);
143 __ stop("assert arg_slots <= 0 and clear low bits"); 143 __ stop("assert arg_slots <= 0 and clear low bits");
144 __ bind(L_ok); 144 __ bind(L_ok);
145 } else { 145 } else {
146 assert(arg_slots.as_constant() <= 0, ""); 146 assert(arg_slots.as_constant() <= 0, "");
171 // pull one word down each time through the loop 171 // pull one word down each time through the loop
172 __ movptr(rbx_temp, Address(rdx_temp, 0)); 172 __ movptr(rbx_temp, Address(rdx_temp, 0));
173 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp); 173 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
174 __ addptr(rdx_temp, wordSize); 174 __ addptr(rdx_temp, wordSize);
175 __ cmpptr(rdx_temp, rax_argslot); 175 __ cmpptr(rdx_temp, rax_argslot);
176 __ jcc(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 181
209 { 209 {
210 // Verify that [argslot..argslot+size) lies within (rsp, rbp). 210 // Verify that [argslot..argslot+size) lies within (rsp, rbp).
211 Label L_ok, L_bad; 211 Label L_ok, L_bad;
212 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 212 __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
213 __ cmpptr(rbx_temp, rbp); 213 __ cmpptr(rbx_temp, rbp);
214 __ jcc(Assembler::above, L_bad); 214 __ jccb(Assembler::above, L_bad);
215 __ cmpptr(rsp, rax_argslot); 215 __ cmpptr(rsp, rax_argslot);
216 __ jcc(Assembler::below, L_ok); 216 __ jccb(Assembler::below, L_ok);
217 __ bind(L_bad); 217 __ bind(L_bad);
218 __ stop("deleted argument(s) must fall within current frame"); 218 __ stop("deleted argument(s) must fall within current frame");
219 __ bind(L_ok); 219 __ bind(L_ok);
220 } 220 }
221 if (arg_slots.is_register()) { 221 if (arg_slots.is_register()) {
222 Label L_ok, L_bad; 222 Label L_ok, L_bad;
223 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); 223 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
224 __ jcc(Assembler::less, L_bad); 224 __ jccb(Assembler::less, L_bad);
225 __ testl(arg_slots.as_register(), -stack_move_unit() - 1); 225 __ testl(arg_slots.as_register(), -stack_move_unit() - 1);
226 __ jcc(Assembler::zero, L_ok); 226 __ jccb(Assembler::zero, L_ok);
227 __ bind(L_bad); 227 __ bind(L_bad);
228 __ stop("assert arg_slots >= 0 and clear low bits"); 228 __ stop("assert arg_slots >= 0 and clear low bits");
229 __ bind(L_ok); 229 __ bind(L_ok);
230 } else { 230 } else {
231 assert(arg_slots.as_constant() >= 0, ""); 231 assert(arg_slots.as_constant() >= 0, "");
256 // pull one word up each time through the loop 256 // pull one word up each time through the loop
257 __ movptr(rbx_temp, Address(rdx_temp, 0)); 257 __ movptr(rbx_temp, Address(rdx_temp, 0));
258 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp); 258 __ movptr(Address(rdx_temp, arg_slots, Address::times_ptr), rbx_temp);
259 __ addptr(rdx_temp, -wordSize); 259 __ addptr(rdx_temp, -wordSize);
260 __ cmpptr(rdx_temp, rsp); 260 __ cmpptr(rdx_temp, rsp);
261 __ jcc(Assembler::greaterEqual, loop); 261 __ jccb(Assembler::greaterEqual, loop);
262 } 262 }
263 263
264 // Now move the argslot up, to point to the just-copied block. 264 // Now move the argslot up, to point to the just-copied block.
265 __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr)); 265 __ lea(rsp, Address(rsp, arg_slots, Address::times_ptr));
266 // And adjust the argslot address to point at the deletion point. 266 // And adjust the argslot address to point at the deletion point.
382 Register rbx_method = rbx_temp; 382 Register rbx_method = rbx_temp;
383 Label no_method; 383 Label no_method;
384 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method 384 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
385 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); 385 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
386 __ testptr(rbx_method, rbx_method); 386 __ testptr(rbx_method, rbx_method);
387 __ jcc(Assembler::zero, no_method); 387 __ jccb(Assembler::zero, no_method);
388 int jobject_oop_offset = 0; 388 int jobject_oop_offset = 0;
389 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject 389 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject
390 __ testptr(rbx_method, rbx_method); 390 __ testptr(rbx_method, rbx_method);
391 __ jcc(Assembler::zero, no_method); 391 __ jccb(Assembler::zero, no_method);
392 __ verify_oop(rbx_method); 392 __ verify_oop(rbx_method);
393 __ push(rdi_pc); // and restore caller PC 393 __ push(rdi_pc); // and restore caller PC
394 __ jmp(rbx_method_fie); 394 __ jmp(rbx_method_fie);
395 395
396 // If we get here, the Java runtime did not do its job of creating the exception. 396 // If we get here, the Java runtime did not do its job of creating the exception.
533 __ movptr(rbx_temp, rcx_bmh_argument); 533 __ movptr(rbx_temp, rcx_bmh_argument);
534 Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 534 Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
535 if (arg_type == T_OBJECT) { 535 if (arg_type == T_OBJECT) {
536 __ movptr(Address(rax_argslot, 0), rbx_temp); 536 __ movptr(Address(rax_argslot, 0), rbx_temp);
537 } else { 537 } else {
538 __ load_sized_value(rbx_temp, prim_value_addr, 538 __ load_sized_value(rdx_temp, prim_value_addr,
539 type2aelembytes(arg_type), is_signed_subword_type(arg_type)); 539 type2aelembytes(arg_type), is_signed_subword_type(arg_type));
540 __ movptr(Address(rax_argslot, 0), rbx_temp); 540 __ movptr(Address(rax_argslot, 0), rdx_temp);
541 #ifndef _LP64 541 #ifndef _LP64
542 if (arg_slots == 2) { 542 if (arg_slots == 2) {
543 __ movl(rbx_temp, prim_value_addr.plus_disp(wordSize)); 543 __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize));
544 __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rbx_temp); 544 __ movl(Address(rax_argslot, Interpreter::stackElementSize()), rdx_temp);
545 } 545 }
546 #endif //_LP64 546 #endif //_LP64
547 break;
548 } 547 }
549 548
550 if (direct_to_method) { 549 if (direct_to_method) {
551 Register rbx_method = rbx_temp; 550 Register rbx_method = rbx_temp;
552 __ movptr(rbx_method, rcx_mh_vmtarget); 551 __ movptr(rbx_method, rcx_mh_vmtarget);
584 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 583 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
585 584
586 Label done; 585 Label done;
587 __ movptr(rdx_temp, vmarg); 586 __ movptr(rdx_temp, vmarg);
588 __ testl(rdx_temp, rdx_temp); 587 __ testl(rdx_temp, rdx_temp);
589 __ jcc(Assembler::zero, done); // no cast if null 588 __ jccb(Assembler::zero, done); // no cast if null
590 __ load_klass(rdx_temp, rdx_temp); 589 __ load_klass(rdx_temp, rdx_temp);
591 590
592 // live at this point: 591 // live at this point:
593 // - rbx_klass: klass required by the target method 592 // - rbx_klass: klass required by the target method
594 // - rdx_temp: argument klass to test 593 // - rdx_temp: argument klass to test
675 // get the new MH: 674 // get the new MH:
676 __ movptr(rcx_recv, rcx_mh_vmtarget); 675 __ movptr(rcx_recv, rcx_mh_vmtarget);
677 // (now we are done with the old MH) 676 // (now we are done with the old MH)
678 677
679 // original 32-bit vmdata word must be of this form: 678 // original 32-bit vmdata word must be of this form:
680 // | MBZ:16 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 | 679 // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
681 __ xchgl(rcx, rbx_vminfo); // free rcx for shifts 680 __ xchgptr(rcx, rbx_vminfo); // free rcx for shifts
682 __ shll(rdx_temp /*, rcx*/); 681 __ shll(rdx_temp /*, rcx*/);
683 Label zero_extend, done; 682 Label zero_extend, done;
684 __ testl(rcx, CONV_VMINFO_SIGN_FLAG); 683 __ testl(rcx, CONV_VMINFO_SIGN_FLAG);
685 __ jcc(Assembler::zero, zero_extend); 684 __ jccb(Assembler::zero, zero_extend);
686 685
687 // this path is taken for int->byte, int->short 686 // this path is taken for int->byte, int->short
688 __ sarl(rdx_temp /*, rcx*/); 687 __ sarl(rdx_temp /*, rcx*/);
689 __ jmp(done); 688 __ jmpb(done);
690 689
691 __ bind(zero_extend); 690 __ bind(zero_extend);
692 // this is taken for int->char 691 // this is taken for int->char
693 __ shrl(rdx_temp /*, rcx*/); 692 __ shrl(rdx_temp /*, rcx*/);
694 693
695 __ bind(done); 694 __ bind(done);
696 __ movptr(vmarg, rdx_temp); 695 __ movl(vmarg, rdx_temp);
697 __ xchgl(rcx, rbx_vminfo); // restore rcx_recv 696 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv
698 697
699 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 698 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
700 } 699 }
701 break; 700 break;
702 701
861 #ifdef ASSERT 860 #ifdef ASSERT
862 { 861 {
863 // Verify that argslot > destslot, by at least swap_bytes. 862 // Verify that argslot > destslot, by at least swap_bytes.
864 Label L_ok; 863 Label L_ok;
865 __ cmpptr(rax_argslot, rbx_destslot); 864 __ cmpptr(rax_argslot, rbx_destslot);
866 __ jcc(Assembler::aboveEqual, L_ok); 865 __ jccb(Assembler::aboveEqual, L_ok);
867 __ stop("source must be above destination (upward rotation)"); 866 __ stop("source must be above destination (upward rotation)");
868 __ bind(L_ok); 867 __ bind(L_ok);
869 } 868 }
870 #endif 869 #endif
871 // work argslot down to destslot, copying contiguous data upwards 870 // work argslot down to destslot, copying contiguous data upwards
877 __ bind(loop); 876 __ bind(loop);
878 __ movptr(rdx_temp, Address(rax_argslot, 0)); 877 __ movptr(rdx_temp, Address(rax_argslot, 0));
879 __ movptr(Address(rax_argslot, swap_bytes), rdx_temp); 878 __ movptr(Address(rax_argslot, swap_bytes), rdx_temp);
880 __ addptr(rax_argslot, -wordSize); 879 __ addptr(rax_argslot, -wordSize);
881 __ cmpptr(rax_argslot, rbx_destslot); 880 __ cmpptr(rax_argslot, rbx_destslot);
882 __ jcc(Assembler::aboveEqual, loop); 881 __ jccb(Assembler::aboveEqual, loop);
883 } else { 882 } else {
884 __ addptr(rax_argslot, swap_bytes); 883 __ addptr(rax_argslot, swap_bytes);
885 #ifdef ASSERT 884 #ifdef ASSERT
886 { 885 {
887 // Verify that argslot < destslot, by at least swap_bytes. 886 // Verify that argslot < destslot, by at least swap_bytes.
888 Label L_ok; 887 Label L_ok;
889 __ cmpptr(rax_argslot, rbx_destslot); 888 __ cmpptr(rax_argslot, rbx_destslot);
890 __ jcc(Assembler::belowEqual, L_ok); 889 __ jccb(Assembler::belowEqual, L_ok);
891 __ stop("source must be below destination (downward rotation)"); 890 __ stop("source must be below destination (downward rotation)");
892 __ bind(L_ok); 891 __ bind(L_ok);
893 } 892 }
894 #endif 893 #endif
895 // work argslot up to destslot, copying contiguous data downwards 894 // work argslot up to destslot, copying contiguous data downwards
901 __ bind(loop); 900 __ bind(loop);
902 __ movptr(rdx_temp, Address(rax_argslot, 0)); 901 __ movptr(rdx_temp, Address(rax_argslot, 0));
903 __ movptr(Address(rax_argslot, -swap_bytes), rdx_temp); 902 __ movptr(Address(rax_argslot, -swap_bytes), rdx_temp);
904 __ addptr(rax_argslot, wordSize); 903 __ addptr(rax_argslot, wordSize);
905 __ cmpptr(rax_argslot, rbx_destslot); 904 __ cmpptr(rax_argslot, rbx_destslot);
906 __ jcc(Assembler::belowEqual, loop); 905 __ jccb(Assembler::belowEqual, loop);
907 } 906 }
908 907
909 // pop the original first chunk into the destination slot, now free 908 // pop the original first chunk into the destination slot, now free
910 for (int i = 0; i < swap_bytes; i += wordSize) { 909 for (int i = 0; i < swap_bytes; i += wordSize) {
911 __ pop(rdx_temp); 910 __ pop(rdx_temp);
967 __ movptr(rdi, Address(rax_argslot, 0)); 966 __ movptr(rdi, Address(rax_argslot, 0));
968 __ movptr(Address(rdx_newarg, 0), rdi); 967 __ movptr(Address(rdx_newarg, 0), rdi);
969 __ addptr(rax_argslot, wordSize); 968 __ addptr(rax_argslot, wordSize);
970 __ addptr(rdx_newarg, wordSize); 969 __ addptr(rdx_newarg, wordSize);
971 __ cmpptr(rdx_newarg, rbx_oldarg); 970 __ cmpptr(rdx_newarg, rbx_oldarg);
972 __ jcc(Assembler::less, loop); 971 __ jccb(Assembler::less, loop);
973 972
974 __ pop(rdi); // restore temp 973 __ pop(rdi); // restore temp
975 974
976 __ movptr(rcx_recv, rcx_mh_vmtarget); 975 __ movptr(rcx_recv, rcx_mh_vmtarget);
977 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 976 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1119 __ movptr(Address(rax_argslot, tag_offset), 1118 __ movptr(Address(rax_argslot, tag_offset),
1120 frame::tag_for_basic_type(elem_type)); 1119 frame::tag_for_basic_type(elem_type));
1121 } 1120 }
1122 __ addptr(rax_argslot, Interpreter::stackElementSize()); 1121 __ addptr(rax_argslot, Interpreter::stackElementSize());
1123 __ cmpptr(rax_argslot, rdx_argslot_limit); 1122 __ cmpptr(rax_argslot, rdx_argslot_limit);
1124 __ jcc(Assembler::less, loop); 1123 __ jccb(Assembler::less, loop);
1125 } else if (length_constant == 0) { 1124 } else if (length_constant == 0) {
1126 __ bind(skip_array_check); 1125 __ bind(skip_array_check);
1127 // nothing to copy 1126 // nothing to copy
1128 } else { 1127 } else {
1129 int elem_offset = elem0_offset; 1128 int elem_offset = elem0_offset;