190 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n)); |
190 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n)); |
191 off += delta; |
191 off += delta; |
192 } |
192 } |
193 } else if(UseSSE >= 2) { |
193 } else if(UseSSE >= 2) { |
194 // Save whole 128bit (16 bytes) XMM regiters |
194 // Save whole 128bit (16 bytes) XMM regiters |
195 if (VM_Version::supports_avx512novl()) { |
195 for (int n = 0; n < num_xmm_regs; n++) { |
196 for (int n = 0; n < num_xmm_regs; n++) { |
196 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n)); |
197 __ vextractf32x4h(Address(rsp, off*wordSize), as_XMMRegister(n), 0); |
197 off += delta; |
198 off += delta; |
|
199 } |
|
200 } else { |
|
201 for (int n = 0; n < num_xmm_regs; n++) { |
|
202 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n)); |
|
203 off += delta; |
|
204 } |
|
205 } |
198 } |
206 } |
199 } |
207 |
200 |
208 if (vect_words > 0) { |
201 if (vect_words > 0) { |
209 assert(vect_words*wordSize == 128, ""); |
202 assert(vect_words*wordSize == 128, ""); |
210 __ subptr(rsp, 128); // Save upper half of YMM registes |
203 __ subptr(rsp, 128); // Save upper half of YMM registes |
211 off = 0; |
|
212 for (int n = 0; n < num_xmm_regs; n++) { |
204 for (int n = 0; n < num_xmm_regs; n++) { |
213 __ vextractf128h(Address(rsp, off++*16), as_XMMRegister(n)); |
205 __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n)); |
214 } |
206 } |
215 if (UseAVX > 2) { |
207 if (UseAVX > 2) { |
216 __ subptr(rsp, 256); // Save upper half of ZMM registes |
208 __ subptr(rsp, 256); // Save upper half of ZMM registes |
217 off = 0; |
|
218 for (int n = 0; n < num_xmm_regs; n++) { |
209 for (int n = 0; n < num_xmm_regs; n++) { |
219 __ vextractf64x4h(Address(rsp, off++*32), as_XMMRegister(n)); |
210 __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1); |
220 } |
211 } |
221 } |
212 } |
222 } |
213 } |
223 |
214 |
224 // Set an oopmap for the call site. This oopmap will map all |
215 // Set an oopmap for the call site. This oopmap will map all |
283 for (int n = 0; n < num_xmm_regs; n++) { |
274 for (int n = 0; n < num_xmm_regs; n++) { |
284 __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize)); |
275 __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize)); |
285 off += delta; |
276 off += delta; |
286 } |
277 } |
287 } else if (UseSSE >= 2) { |
278 } else if (UseSSE >= 2) { |
288 if (VM_Version::supports_avx512novl()) { |
279 for (int n = 0; n < num_xmm_regs; n++) { |
|
280 __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes)); |
|
281 off += delta; |
|
282 } |
|
283 } |
|
284 if (restore_vectors) { |
|
285 assert(additional_frame_bytes == 128, ""); |
|
286 if (UseAVX > 2) { |
|
287 // Restore upper half of ZMM registers. |
289 for (int n = 0; n < num_xmm_regs; n++) { |
288 for (int n = 0; n < num_xmm_regs; n++) { |
290 __ vinsertf32x4h(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes), 0); |
289 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1); |
291 off += delta; |
|
292 } |
|
293 } else { |
|
294 for (int n = 0; n < num_xmm_regs; n++) { |
|
295 __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes)); |
|
296 off += delta; |
|
297 } |
|
298 } |
|
299 } |
|
300 if (restore_vectors) { |
|
301 if (UseAVX > 2) { |
|
302 off = 0; |
|
303 for (int n = 0; n < num_xmm_regs; n++) { |
|
304 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, off++*32)); |
|
305 } |
290 } |
306 __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes |
291 __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes |
307 } |
292 } |
308 // Restore upper half of YMM registes. |
293 // Restore upper half of YMM registes. |
309 assert(additional_frame_bytes == 128, ""); |
|
310 off = 0; |
|
311 for (int n = 0; n < num_xmm_regs; n++) { |
294 for (int n = 0; n < num_xmm_regs; n++) { |
312 __ vinsertf128h(as_XMMRegister(n), Address(rsp, off++*16)); |
295 __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16)); |
313 } |
296 } |
314 __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes |
297 __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes |
315 } |
298 } |
316 __ pop_FPU_state(); |
299 __ pop_FPU_state(); |
317 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers |
300 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers |
2560 // Need to have an oopmap that tells fetch_unroll_info where to |
2543 // Need to have an oopmap that tells fetch_unroll_info where to |
2561 // find any register it might need. |
2544 // find any register it might need. |
2562 |
2545 |
2563 oop_maps->add_gc_map( __ pc()-start, map); |
2546 oop_maps->add_gc_map( __ pc()-start, map); |
2564 |
2547 |
2565 // Discard arg to fetch_unroll_info |
2548 // Discard args to fetch_unroll_info |
|
2549 __ pop(rcx); |
2566 __ pop(rcx); |
2550 __ pop(rcx); |
2567 |
2551 |
2568 __ get_thread(rcx); |
2552 __ get_thread(rcx); |
2569 __ reset_last_Java_frame(rcx, false, false); |
2553 __ reset_last_Java_frame(rcx, false, false); |
2570 |
2554 |
2573 |
2557 |
2574 // Move the unpack kind to a safe place in the UnrollBlock because |
2558 // Move the unpack kind to a safe place in the UnrollBlock because |
2575 // we are very short of registers |
2559 // we are very short of registers |
2576 |
2560 |
2577 Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()); |
2561 Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()); |
2578 // retrieve the deopt kind from where we left it. |
2562 // retrieve the deopt kind from the UnrollBlock. |
2579 __ pop(rax); |
2563 __ movl(rax, unpack_kind); |
2580 __ movl(unpack_kind, rax); // save the unpack_kind value |
|
2581 |
2564 |
2582 Label noException; |
2565 Label noException; |
2583 __ cmpl(rax, Deoptimization::Unpack_exception); // Was exception pending? |
2566 __ cmpl(rax, Deoptimization::Unpack_exception); // Was exception pending? |
2584 __ jcc(Assembler::notEqual, noException); |
2567 __ jcc(Assembler::notEqual, noException); |
2585 __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); |
2568 __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); |
2785 MacroAssembler* masm = new MacroAssembler(&buffer); |
2768 MacroAssembler* masm = new MacroAssembler(&buffer); |
2786 |
2769 |
2787 enum frame_layout { |
2770 enum frame_layout { |
2788 arg0_off, // thread sp + 0 // Arg location for |
2771 arg0_off, // thread sp + 0 // Arg location for |
2789 arg1_off, // unloaded_class_index sp + 1 // calling C |
2772 arg1_off, // unloaded_class_index sp + 1 // calling C |
|
2773 arg2_off, // exec_mode sp + 2 |
2790 // The frame sender code expects that rbp will be in the "natural" place and |
2774 // The frame sender code expects that rbp will be in the "natural" place and |
2791 // will override any oopMap setting for it. We must therefore force the layout |
2775 // will override any oopMap setting for it. We must therefore force the layout |
2792 // so that it agrees with the frame sender code. |
2776 // so that it agrees with the frame sender code. |
2793 rbp_off, // callee saved register sp + 2 |
2777 rbp_off, // callee saved register sp + 3 |
2794 return_off, // slot for return address sp + 3 |
2778 return_off, // slot for return address sp + 4 |
2795 framesize |
2779 framesize |
2796 }; |
2780 }; |
2797 |
2781 |
2798 address start = __ pc(); |
2782 address start = __ pc(); |
2799 |
2783 |
2821 // crud. We cannot block on this call, no GC can happen. Call should |
2805 // crud. We cannot block on this call, no GC can happen. Call should |
2822 // capture callee-saved registers as well as return values. |
2806 // capture callee-saved registers as well as return values. |
2823 __ movptr(Address(rsp, arg0_off*wordSize), rdx); |
2807 __ movptr(Address(rsp, arg0_off*wordSize), rdx); |
2824 // argument already in ECX |
2808 // argument already in ECX |
2825 __ movl(Address(rsp, arg1_off*wordSize),rcx); |
2809 __ movl(Address(rsp, arg1_off*wordSize),rcx); |
|
2810 __ movl(Address(rsp, arg2_off*wordSize), Deoptimization::Unpack_uncommon_trap); |
2826 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); |
2811 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); |
2827 |
2812 |
2828 // Set an oopmap for the call site |
2813 // Set an oopmap for the call site |
2829 OopMapSet *oop_maps = new OopMapSet(); |
2814 OopMapSet *oop_maps = new OopMapSet(); |
2830 OopMap* map = new OopMap( framesize, 0 ); |
2815 OopMap* map = new OopMap( framesize, 0 ); |
2836 |
2821 |
2837 __ reset_last_Java_frame(rcx, false, false); |
2822 __ reset_last_Java_frame(rcx, false, false); |
2838 |
2823 |
2839 // Load UnrollBlock into EDI |
2824 // Load UnrollBlock into EDI |
2840 __ movptr(rdi, rax); |
2825 __ movptr(rdi, rax); |
|
2826 |
|
2827 #ifdef ASSERT |
|
2828 { Label L; |
|
2829 __ cmpptr(Address(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()), |
|
2830 (int32_t)Deoptimization::Unpack_uncommon_trap); |
|
2831 __ jcc(Assembler::equal, L); |
|
2832 __ stop("SharedRuntime::generate_deopt_blob: expected Unpack_uncommon_trap"); |
|
2833 __ bind(L); |
|
2834 } |
|
2835 #endif |
2841 |
2836 |
2842 // Pop all the frames we must move/replace. |
2837 // Pop all the frames we must move/replace. |
2843 // |
2838 // |
2844 // Frame picture (youngest to oldest) |
2839 // Frame picture (youngest to oldest) |
2845 // 1: self-frame (no frame link) |
2840 // 1: self-frame (no frame link) |