585 } 586 587 // given the MethodType, find out where the MH argument is buried 588 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp))); 589 Register rdx_vmslots = rdx_temp; 590 __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp))); 591 Address mh_receiver_slot_addr = __ argument_address(rdx_vmslots); 592 __ movptr(rcx_recv, mh_receiver_slot_addr); 593 594 trace_method_handle(_masm, "invokeExact"); 595 596 __ check_method_handle_type(rax_mtype, rcx_recv, rdi_temp, wrong_method_type); 597 598 // Nobody uses the MH receiver slot after this. Make sure. 599 DEBUG_ONLY(__ movptr(mh_receiver_slot_addr, (int32_t)0x999999)); 600 601 __ jump_to_method_handle_entry(rcx_recv, rdi_temp); 602 603 // error path for invokeExact (only) 604 __ bind(invoke_exact_error_path); 605 // jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 606 Register rdx_last_Java_sp = rdx_temp; 607 __ lea(rdx_last_Java_sp, __ argument_address(constant(0))); 608 __ super_call_VM(noreg, 609 rdx_last_Java_sp, 610 CAST_FROM_FN_PTR(address, 611 InterpreterRuntime::throw_WrongMethodTypeException), 612 // pass required type, then failing mh object 613 rax_mtype, rcx_recv); 614 615 // for invokeGeneric (only), apply argument and result conversions on the fly 616 __ bind(invoke_generic_slow_path); 617 #ifdef ASSERT 618 if (VerifyMethodHandles) { 619 Label L; 620 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeGeneric); 621 __ jcc(Assembler::equal, L); 622 __ stop("bad methodOop::intrinsic_id"); 623 __ bind(L); 624 } 625 #endif //ASSERT 626 Register rbx_temp = rbx_method; // don't need it now 627 628 // make room on the stack for another pointer: 629 Register rcx_argslot = rcx_recv; 630 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1)); 631 insert_arg_slots(_masm, 2 * stack_move_unit(), 632 rcx_argslot, rbx_temp, rdx_temp); 633 1158 address interp_entry = __ pc(); 1159 1160 trace_method_handle(_masm, entry_name(ek)); 1161 1162 BLOCK_COMMENT(err_msg("Entry %s {", entry_name(ek))); 1163 1164 switch ((int) ek) { 1165 case _raise_exception: 1166 { 1167 // Not a real MH entry, but rather shared code for raising an 1168 // exception. Since we use the compiled entry, arguments are 1169 // expected in compiler argument registers. 1170 assert(raise_exception_method(), "must be set"); 1171 assert(raise_exception_method()->from_compiled_entry(), "method must be linked"); 1172 1173 const Register rdi_pc = rax; 1174 __ pop(rdi_pc); // caller PC 1175 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started 1176 1177 Register rbx_method = rbx_temp; 1178 Label L_no_method; 1179 // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method 1180 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); 1181 __ testptr(rbx_method, rbx_method); 1182 __ jccb(Assembler::zero, L_no_method); 1183 1184 const int jobject_oop_offset = 0; 1185 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject 1186 __ testptr(rbx_method, rbx_method); 1187 __ jccb(Assembler::zero, L_no_method); 1188 __ verify_oop(rbx_method); 1189 1190 NOT_LP64(__ push(rarg2_required)); 1191 __ push(rdi_pc); // restore caller PC 1192 __ jmp(rbx_method_fce); // jump to compiled entry 1193 1194 // Do something that is at least causes a valid throw from the interpreter. 1195 __ bind(L_no_method); 1196 __ push(rarg2_required); 1197 __ push(rarg1_actual); 1198 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 1199 } 1200 break; 1201 1202 case _invokestatic_mh: 1203 case _invokespecial_mh: 1204 { 1205 Register rbx_method = rbx_temp; 1206 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop 1207 __ verify_oop(rbx_method); 1208 // same as TemplateTable::invokestatic or invokespecial, 1209 // minus the CP setup and profiling: 1210 if (ek == _invokespecial_mh) { 1211 // Must load & check the first argument before entering the target method. 1212 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); 1213 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); 1214 __ null_check(rcx_recv); 1215 __ verify_oop(rcx_recv); 1216 } 1217 __ jmp(rbx_method_fie); 1218 } | 585 } 586 587 // given the MethodType, find out where the MH argument is buried 588 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp))); 589 Register rdx_vmslots = rdx_temp; 590 __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp))); 591 Address mh_receiver_slot_addr = __ argument_address(rdx_vmslots); 592 __ movptr(rcx_recv, mh_receiver_slot_addr); 593 594 trace_method_handle(_masm, "invokeExact"); 595 596 __ check_method_handle_type(rax_mtype, rcx_recv, rdi_temp, wrong_method_type); 597 598 // Nobody uses the MH receiver slot after this. Make sure. 599 DEBUG_ONLY(__ movptr(mh_receiver_slot_addr, (int32_t)0x999999)); 600 601 __ jump_to_method_handle_entry(rcx_recv, rdi_temp); 602 603 // error path for invokeExact (only) 604 __ bind(invoke_exact_error_path); 605 // Stub wants expected type in rax and the actual type in rcx 606 __ jump(ExternalAddress(StubRoutines::throw_WrongMethodTypeException_entry())); 607 608 // for invokeGeneric (only), apply argument and result conversions on the fly 609 __ bind(invoke_generic_slow_path); 610 #ifdef ASSERT 611 if (VerifyMethodHandles) { 612 Label L; 613 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeGeneric); 614 __ jcc(Assembler::equal, L); 615 __ stop("bad methodOop::intrinsic_id"); 616 __ bind(L); 617 } 618 #endif //ASSERT 619 Register rbx_temp = rbx_method; // don't need it now 620 621 // make room on the stack for another pointer: 622 Register rcx_argslot = rcx_recv; 623 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1)); 624 insert_arg_slots(_masm, 2 * stack_move_unit(), 625 rcx_argslot, rbx_temp, rdx_temp); 626 1151 address interp_entry = __ pc(); 1152 1153 trace_method_handle(_masm, entry_name(ek)); 1154 1155 BLOCK_COMMENT(err_msg("Entry %s {", entry_name(ek))); 1156 1157 switch ((int) ek) { 1158 case _raise_exception: 1159 { 1160 // Not a real MH entry, but rather shared code for raising an 1161 // exception. Since we use the compiled entry, arguments are 1162 // expected in compiler argument registers. 1163 assert(raise_exception_method(), "must be set"); 1164 assert(raise_exception_method()->from_compiled_entry(), "method must be linked"); 1165 1166 const Register rdi_pc = rax; 1167 __ pop(rdi_pc); // caller PC 1168 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started 1169 1170 Register rbx_method = rbx_temp; 1171 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); 1172 1173 const int jobject_oop_offset = 0; 1174 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject 1175 __ verify_oop(rbx_method); 1176 1177 NOT_LP64(__ push(rarg2_required)); 1178 __ push(rdi_pc); // restore caller PC 1179 __ jmp(rbx_method_fce); // jump to compiled entry 1180 } 1181 break; 1182 1183 case _invokestatic_mh: 1184 case _invokespecial_mh: 1185 { 1186 Register rbx_method = rbx_temp; 1187 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop 1188 __ verify_oop(rbx_method); 1189 // same as TemplateTable::invokestatic or invokespecial, 1190 // minus the CP setup and profiling: 1191 if (ek == _invokespecial_mh) { 1192 // Must load & check the first argument before entering the target method. 1193 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); 1194 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); 1195 __ null_check(rcx_recv); 1196 __ verify_oop(rcx_recv); 1197 } 1198 __ jmp(rbx_method_fie); 1199 } |