Mercurial > hg > graal-compiler
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 |