comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 1846:d55217dc206f

6829194: JSR 292 needs to support compressed oops Reviewed-by: kvn, jrose
author twisti
date Mon, 11 Oct 2010 04:18:58 -0700
parents c93c652551b5
children beba40b26a79
comparison
equal deleted inserted replaced
1845:a222fcfba398 1846:d55217dc206f
121 tem = rax_mtype; // in case there is another indirection 121 tem = rax_mtype; // in case there is another indirection
122 } 122 }
123 } 123 }
124 124
125 // given the MethodType, find out where the MH argument is buried 125 // given the MethodType, find out where the MH argument is buried
126 __ movptr(rdx_temp, Address(rax_mtype, 126 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
127 __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
128 Register rdx_vmslots = rdx_temp; 127 Register rdx_vmslots = rdx_temp;
129 __ movl(rdx_vmslots, Address(rdx_temp, 128 __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
130 __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
131 __ movptr(rcx_recv, __ argument_address(rdx_vmslots)); 129 __ movptr(rcx_recv, __ argument_address(rdx_vmslots));
132 130
133 trace_method_handle(_masm, "invokeExact"); 131 trace_method_handle(_masm, "invokeExact");
134 132
135 __ check_method_handle_type(rax_mtype, rcx_recv, rdi_temp, wrong_method_type); 133 __ check_method_handle_type(rax_mtype, rcx_recv, rdi_temp, wrong_method_type);
152 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1)); 150 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1));
153 insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK, 151 insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK,
154 rcx_argslot, rbx_temp, rdx_temp); 152 rcx_argslot, rbx_temp, rdx_temp);
155 153
156 // load up an adapter from the calling type (Java weaves this) 154 // load up an adapter from the calling type (Java weaves this)
157 __ movptr(rdx_temp, Address(rax_mtype, 155 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
158 __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, rdi_temp)));
159 Register rdx_adapter = rdx_temp; 156 Register rdx_adapter = rdx_temp;
160 // movptr(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes())); 157 // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes()));
161 // deal with old JDK versions: 158 // deal with old JDK versions:
162 __ lea(rdi_temp, Address(rdx_temp, 159 __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
163 __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
164 __ cmpptr(rdi_temp, rdx_temp); 160 __ cmpptr(rdi_temp, rdx_temp);
165 Label sorry_no_invoke_generic; 161 Label sorry_no_invoke_generic;
166 __ jccb(Assembler::below, sorry_no_invoke_generic); 162 __ jcc(Assembler::below, sorry_no_invoke_generic);
167 163
168 __ movptr(rdx_adapter, Address(rdi_temp, 0)); 164 __ load_heap_oop(rdx_adapter, Address(rdi_temp, 0));
169 __ testptr(rdx_adapter, rdx_adapter); 165 __ testptr(rdx_adapter, rdx_adapter);
170 __ jccb(Assembler::zero, sorry_no_invoke_generic); 166 __ jcc(Assembler::zero, sorry_no_invoke_generic);
171 __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter); 167 __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter);
172 // As a trusted first argument, pass the type being called, so the adapter knows 168 // As a trusted first argument, pass the type being called, so the adapter knows
173 // the actual types of the arguments and return values. 169 // the actual types of the arguments and return values.
174 // (Generic invokers are shared among form-families of method-type.) 170 // (Generic invokers are shared among form-families of method-type.)
175 __ movptr(Address(rcx_argslot, 0 * Interpreter::stackElementSize), rax_mtype); 171 __ movptr(Address(rcx_argslot, 0 * Interpreter::stackElementSize), rax_mtype);
429 __ nop(); // empty stubs make SG sick 425 __ nop(); // empty stubs make SG sick
430 return; 426 return;
431 } 427 }
432 428
433 address interp_entry = __ pc(); 429 address interp_entry = __ pc();
434 if (UseCompressedOops) __ unimplemented("UseCompressedOops");
435 430
436 trace_method_handle(_masm, entry_name(ek)); 431 trace_method_handle(_masm, entry_name(ek));
437 432
438 BLOCK_COMMENT(entry_name(ek)); 433 BLOCK_COMMENT(entry_name(ek));
439 434
487 482
488 case _invokestatic_mh: 483 case _invokestatic_mh:
489 case _invokespecial_mh: 484 case _invokespecial_mh:
490 { 485 {
491 Register rbx_method = rbx_temp; 486 Register rbx_method = rbx_temp;
492 __ movptr(rbx_method, rcx_mh_vmtarget); // target is a methodOop 487 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop
493 __ verify_oop(rbx_method); 488 __ verify_oop(rbx_method);
494 // same as TemplateTable::invokestatic or invokespecial, 489 // same as TemplateTable::invokestatic or invokespecial,
495 // minus the CP setup and profiling: 490 // minus the CP setup and profiling:
496 if (ek == _invokespecial_mh) { 491 if (ek == _invokespecial_mh) {
497 // Must load & check the first argument before entering the target method. 492 // Must load & check the first argument before entering the target method.
544 539
545 // pick out the interface and itable index from the MH. 540 // pick out the interface and itable index from the MH.
546 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); 541 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
547 Register rdx_intf = rdx_temp; 542 Register rdx_intf = rdx_temp;
548 Register rbx_index = rbx_temp; 543 Register rbx_index = rbx_temp;
549 __ movptr(rdx_intf, rcx_mh_vmtarget); 544 __ load_heap_oop(rdx_intf, rcx_mh_vmtarget);
550 __ movl(rbx_index, rcx_dmh_vmindex); 545 __ movl(rbx_index, rcx_dmh_vmindex);
551 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); 546 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
552 __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes()); 547 __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
553 548
554 // get receiver klass 549 // get receiver klass
555 Register rax_klass = rax_argslot; 550 Register rax_klass = rax_argslot;
600 __ lea(rax_argslot, __ argument_address(rax_argslot)); 595 __ lea(rax_argslot, __ argument_address(rax_argslot));
601 insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, 596 insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask,
602 rax_argslot, rbx_temp, rdx_temp); 597 rax_argslot, rbx_temp, rdx_temp);
603 598
604 // store bound argument into the new stack slot: 599 // store bound argument into the new stack slot:
605 __ movptr(rbx_temp, rcx_bmh_argument); 600 __ load_heap_oop(rbx_temp, rcx_bmh_argument);
606 Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 601 Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
607 if (arg_type == T_OBJECT) { 602 if (arg_type == T_OBJECT) {
608 __ movptr(Address(rax_argslot, 0), rbx_temp); 603 __ movptr(Address(rax_argslot, 0), rbx_temp);
609 } else { 604 } else {
610 __ load_sized_value(rdx_temp, prim_value_addr, 605 __ load_sized_value(rdx_temp, prim_value_addr,
618 #endif //_LP64 613 #endif //_LP64
619 } 614 }
620 615
621 if (direct_to_method) { 616 if (direct_to_method) {
622 Register rbx_method = rbx_temp; 617 Register rbx_method = rbx_temp;
623 __ movptr(rbx_method, rcx_mh_vmtarget); 618 __ load_heap_oop(rbx_method, rcx_mh_vmtarget);
624 __ verify_oop(rbx_method); 619 __ verify_oop(rbx_method);
625 __ jmp(rbx_method_fie); 620 __ jmp(rbx_method_fie);
626 } else { 621 } else {
627 __ movptr(rcx_recv, rcx_mh_vmtarget); 622 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
628 __ verify_oop(rcx_recv); 623 __ verify_oop(rcx_recv);
629 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 624 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
630 } 625 }
631 } 626 }
632 break; 627 break;
633 628
634 case _adapter_retype_only: 629 case _adapter_retype_only:
635 case _adapter_retype_raw: 630 case _adapter_retype_raw:
636 // immediately jump to the next MH layer: 631 // immediately jump to the next MH layer:
637 __ movptr(rcx_recv, rcx_mh_vmtarget); 632 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
638 __ verify_oop(rcx_recv); 633 __ verify_oop(rcx_recv);
639 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 634 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
640 // This is OK when all parameter types widen. 635 // This is OK when all parameter types widen.
641 // It is also OK when a return type narrows. 636 // It is also OK when a return type narrows.
642 break; 637 break;
649 // check a reference argument before jumping to the next layer of MH: 644 // check a reference argument before jumping to the next layer of MH:
650 __ movl(rax_argslot, rcx_amh_vmargslot); 645 __ movl(rax_argslot, rcx_amh_vmargslot);
651 vmarg = __ argument_address(rax_argslot); 646 vmarg = __ argument_address(rax_argslot);
652 647
653 // What class are we casting to? 648 // What class are we casting to?
654 __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object! 649 __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
655 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 650 __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
656 651
657 Label done; 652 Label done;
658 __ movptr(rdx_temp, vmarg); 653 __ movptr(rdx_temp, vmarg);
659 __ testptr(rdx_temp, rdx_temp); 654 __ testptr(rdx_temp, rdx_temp);
660 __ jccb(Assembler::zero, done); // no cast if null 655 __ jcc(Assembler::zero, done); // no cast if null
661 __ load_klass(rdx_temp, rdx_temp); 656 __ load_klass(rdx_temp, rdx_temp);
662 657
663 // live at this point: 658 // live at this point:
664 // - rbx_klass: klass required by the target method 659 // - rbx_klass: klass required by the target method
665 // - rdx_temp: argument klass to test 660 // - rdx_temp: argument klass to test
670 // Call the wrong_method_type stub, passing the failing argument type in rax. 665 // Call the wrong_method_type stub, passing the failing argument type in rax.
671 Register rax_mtype = rax_argslot; 666 Register rax_mtype = rax_argslot;
672 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field 667 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field
673 __ movptr(rdx_temp, vmarg); 668 __ movptr(rdx_temp, vmarg);
674 669
675 __ pushptr(rcx_amh_argument); // required class 670 __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class
676 __ push(rdx_temp); // bad object 671 __ push(rbx_klass);
677 __ push((int)Bytecodes::_checkcast); // who is complaining? 672 __ push(rdx_temp); // bad object
673 __ push((int)Bytecodes::_checkcast); // who is complaining?
678 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); 674 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
679 675
680 __ bind(done); 676 __ bind(done);
681 // get the new MH: 677 // get the new MH:
682 __ movptr(rcx_recv, rcx_mh_vmtarget); 678 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
683 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 679 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
684 } 680 }
685 break; 681 break;
686 682
687 case _adapter_prim_to_prim: 683 case _adapter_prim_to_prim:
739 Register rbx_vminfo = rbx_temp; 735 Register rbx_vminfo = rbx_temp;
740 __ movl(rbx_vminfo, rcx_amh_conversion); 736 __ movl(rbx_vminfo, rcx_amh_conversion);
741 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); 737 assert(CONV_VMINFO_SHIFT == 0, "preshifted");
742 738
743 // get the new MH: 739 // get the new MH:
744 __ movptr(rcx_recv, rcx_mh_vmtarget); 740 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
745 // (now we are done with the old MH) 741 // (now we are done with the old MH)
746 742
747 // original 32-bit vmdata word must be of this form: 743 // original 32-bit vmdata word must be of this form:
748 // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 | 744 // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
749 __ xchgptr(rcx, rbx_vminfo); // free rcx for shifts 745 __ xchgptr(rcx, rbx_vminfo); // free rcx for shifts
814 break; 810 break;
815 default: 811 default:
816 ShouldNotReachHere(); 812 ShouldNotReachHere();
817 } 813 }
818 814
819 __ movptr(rcx_recv, rcx_mh_vmtarget); 815 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
820 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 816 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
821 } 817 }
822 break; 818 break;
823 819
824 case _adapter_opt_f2d: // optimized subcase of adapt_prim_to_prim 820 case _adapter_opt_f2d: // optimized subcase of adapt_prim_to_prim
856 if (ek == _adapter_opt_d2f) { 852 if (ek == _adapter_opt_d2f) {
857 remove_arg_slots(_masm, -stack_move_unit(), 853 remove_arg_slots(_masm, -stack_move_unit(),
858 rax_argslot, rbx_temp, rdx_temp); 854 rax_argslot, rbx_temp, rdx_temp);
859 } 855 }
860 856
861 __ movptr(rcx_recv, rcx_mh_vmtarget); 857 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
862 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 858 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
863 } 859 }
864 break; 860 break;
865 861
866 case _adapter_prim_to_ref: 862 case _adapter_prim_to_ref:
967 __ pop(rdx_temp); 963 __ pop(rdx_temp);
968 __ movptr(Address(rbx_destslot, i), rdx_temp); 964 __ movptr(Address(rbx_destslot, i), rdx_temp);
969 } 965 }
970 } 966 }
971 967
972 __ movptr(rcx_recv, rcx_mh_vmtarget); 968 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
973 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 969 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
974 } 970 }
975 break; 971 break;
976 972
977 case _adapter_dup_args: 973 case _adapter_dup_args:
1027 __ cmpptr(rdx_newarg, rbx_oldarg); 1023 __ cmpptr(rdx_newarg, rbx_oldarg);
1028 __ jccb(Assembler::less, loop); 1024 __ jccb(Assembler::less, loop);
1029 1025
1030 __ pop(rdi); // restore temp 1026 __ pop(rdi); // restore temp
1031 1027
1032 __ movptr(rcx_recv, rcx_mh_vmtarget); 1028 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
1033 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1029 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1034 } 1030 }
1035 break; 1031 break;
1036 1032
1037 case _adapter_drop_args: 1033 case _adapter_drop_args:
1050 remove_arg_slots(_masm, rdi_stack_move, 1046 remove_arg_slots(_masm, rdi_stack_move,
1051 rax_argslot, rbx_temp, rdx_temp); 1047 rax_argslot, rbx_temp, rdx_temp);
1052 1048
1053 __ pop(rdi); // restore temp 1049 __ pop(rdi); // restore temp
1054 1050
1055 __ movptr(rcx_recv, rcx_mh_vmtarget); 1051 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
1056 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1052 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1057 } 1053 }
1058 break; 1054 break;
1059 1055
1060 case _adapter_collect_args: 1056 case _adapter_collect_args:
1101 __ null_check(rsi_array, oopDesc::klass_offset_in_bytes()); 1097 __ null_check(rsi_array, oopDesc::klass_offset_in_bytes());
1102 __ load_klass(rdx_array_klass, rsi_array); 1098 __ load_klass(rdx_array_klass, rsi_array);
1103 1099
1104 // Check the array type. 1100 // Check the array type.
1105 Register rbx_klass = rbx_temp; 1101 Register rbx_klass = rbx_temp;
1106 __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object! 1102 __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
1107 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 1103 __ load_heap_oop(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
1108 1104
1109 Label ok_array_klass, bad_array_klass, bad_array_length; 1105 Label ok_array_klass, bad_array_klass, bad_array_length;
1110 __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass); 1106 __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi, ok_array_klass);
1111 // If we get here, the type check failed! 1107 // If we get here, the type check failed!
1112 __ jmp(bad_array_klass); 1108 __ jmp(bad_array_klass);
1184 } 1180 }
1185 } 1181 }
1186 1182
1187 // Arguments are spread. Move to next method handle. 1183 // Arguments are spread. Move to next method handle.
1188 UNPUSH_RSI_RDI; 1184 UNPUSH_RSI_RDI;
1189 __ movptr(rcx_recv, rcx_mh_vmtarget); 1185 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
1190 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1186 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1191 1187
1192 __ bind(bad_array_klass); 1188 __ bind(bad_array_klass);
1193 UNPUSH_RSI_RDI; 1189 UNPUSH_RSI_RDI;
1194 __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type 1190 __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type