address generate_d2i_wrapper( address fcn ) { StubCodeMark mark(this, "StubRoutines", "d2i_wrapper"); address start = __ pc(); // Capture info about frame layout enum layout { FPUState_off = 0, ebp_off = FPUStateSizeInWords, edi_off, esi_off, ecx_off, ebx_off, saved_argument_off, saved_argument_off2, // 2nd half of double framesize }; assert(FPUStateSizeInWords == 27, "update stack layout"); // Save outgoing argument to stack across push_FPU_state() __ subl(esp, wordSize * 2); __ fstp_d(Address(esp)); // Save CPU & FPU state __ pushl(ebx); __ pushl(ecx); __ pushl(esi); __ pushl(edi); __ pushl(ebp); __ push_FPU_state(); // push_FPU_state() resets the FP top of stack // Load original double into FP top of stack __ fld_d(Address(esp, saved_argument_off * wordSize)); // Store double into stack as outgoing argument __ subl(esp, wordSize*2); __ fst_d(Address(esp)); // Prepare FPU for doing math in C-land __ empty_FPU_stack(); // Call the C code to massage the double. Result in EAX __ call_VM_leaf( fcn, 2 ); // Restore CPU & FPU state __ pop_FPU_state(); __ popl(ebp); __ popl(edi); __ popl(esi); __ popl(ecx); __ popl(ebx); __ addl(esp, wordSize * 2); __ ret(0); return start; }
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { if (!TraceMethodHandles) return; BLOCK_COMMENT("trace_method_handle {"); __ enter(); __ andptr(rsp, -16); // align stack if needed for FPU state __ pusha(); __ mov(rbx, rsp); // for retreiving saved_regs // Note: saved_regs must be in the entered frame for the // robust stack walking implemented in trace_method_handle_stub. // save FP result, valid at some call sites (adapter_opt_return_float, ...) __ increment(rsp, -2 * wordSize); if (UseSSE >= 2) { __ movdbl(Address(rsp, 0), xmm0); } else if (UseSSE == 1) { __ movflt(Address(rsp, 0), xmm0); } else { __ fst_d(Address(rsp, 0)); } // Incoming state: // rcx: method handle // // To avoid calling convention issues, build a record on the stack // and pass the pointer to that instead. __ push(rbp); // entry_sp (with extra align space) __ push(rbx); // pusha saved_regs __ push(rcx); // mh __ push(rcx); // slot for adaptername __ movptr(Address(rsp, 0), (intptr_t) adaptername); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp); __ increment(rsp, sizeof(MethodHandleStubArguments)); if (UseSSE >= 2) { __ movdbl(xmm0, Address(rsp, 0)); } else if (UseSSE == 1) { __ movflt(xmm0, Address(rsp, 0)); } else { __ fld_d(Address(rsp, 0)); } __ increment(rsp, 2 * wordSize); __ popa(); __ leave(); BLOCK_COMMENT("} trace_method_handle"); }