src/cpu/x86/vm/methodHandles_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7055355 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/methodHandles_x86.cpp

Print this page




 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     }


src/cpu/x86/vm/methodHandles_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File