6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "classfile/vmIntrinsics.hpp"
28 #include "compiler/oopMap.hpp"
29 #include "gc/shared/barrierSet.hpp"
30 #include "gc/shared/barrierSetAssembler.hpp"
31 #include "gc/shared/barrierSetNMethod.hpp"
32 #include "gc/shared/gc_globals.hpp"
33 #include "memory/universe.hpp"
34 #include "prims/jvmtiExport.hpp"
35 #include "runtime/arguments.hpp"
36 #include "runtime/javaThread.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #include "runtime/stubRoutines.hpp"
39 #include "stubGenerator_x86_64.hpp"
40 #ifdef COMPILER2
41 #include "opto/runtime.hpp"
42 #include "opto/c2_globals.hpp"
43 #endif
44 #if INCLUDE_JVMCI
45 #include "jvmci/jvmci_globals.hpp"
46 #endif
47 #if INCLUDE_ZGC
48 #include "gc/z/zThreadLocalData.hpp"
49 #endif
50 #if INCLUDE_JFR
51 #include "jfr/support/jfrIntrinsics.hpp"
52 #endif
53
54 // For a more detailed description of the stub routine structure
55 // see the comment in stubRoutines.hpp
56
57 #define __ _masm->
58 #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
300 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1
301 __ BIND(loop);
302 __ movptr(rax, Address(c_rarg2, 0));// get parameter
303 __ addptr(c_rarg2, wordSize); // advance to next parameter
304 __ decrementl(c_rarg1); // decrement counter
305 __ push(rax); // pass parameter
306 __ jcc(Assembler::notZero, loop);
307
308 // call Java function
309 __ BIND(parameters_done);
310 __ movptr(rbx, method); // get Method*
311 __ movptr(c_rarg1, entry_point); // get entry_point
312 __ mov(r13, rsp); // set sender sp
313 BLOCK_COMMENT("call Java function");
314 __ call(c_rarg1);
315
316 BLOCK_COMMENT("call_stub_return_address:");
317 return_address = __ pc();
318
319 // store result depending on type (everything that is not
320 // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
321 __ movptr(c_rarg0, result);
322 Label is_long, is_float, is_double, exit;
323 __ movl(c_rarg1, result_type);
324 __ cmpl(c_rarg1, T_OBJECT);
325 __ jcc(Assembler::equal, is_long);
326 __ cmpl(c_rarg1, T_LONG);
327 __ jcc(Assembler::equal, is_long);
328 __ cmpl(c_rarg1, T_FLOAT);
329 __ jcc(Assembler::equal, is_float);
330 __ cmpl(c_rarg1, T_DOUBLE);
331 __ jcc(Assembler::equal, is_double);
332
333 // handle T_INT case
334 __ movl(Address(c_rarg0, 0), rax);
335
336 __ BIND(exit);
337
338 // pop parameters
339 __ lea(rsp, rsp_after_call);
340
341 #ifdef ASSERT
342 // verify that threads correspond
343 {
344 Label L1, L2, L3;
345 __ cmpptr(r15_thread, thread);
346 __ jcc(Assembler::equal, L1);
347 __ stop("StubRoutines::call_stub: r15_thread is corrupted");
348 __ bind(L1);
349 __ get_thread(rbx);
350 __ cmpptr(r15_thread, thread);
351 __ jcc(Assembler::equal, L2);
352 __ stop("StubRoutines::call_stub: r15_thread is modified by call");
353 __ bind(L2);
354 __ cmpptr(r15_thread, rbx);
378 __ movptr(r13, r13_save);
379 __ movptr(r12, r12_save);
380 __ movptr(rbx, rbx_save);
381
382 #ifdef _WIN64
383 __ movptr(rdi, rdi_save);
384 __ movptr(rsi, rsi_save);
385 #else
386 __ ldmxcsr(mxcsr_save);
387 #endif
388
389 // restore rsp
390 __ addptr(rsp, -rsp_after_call_off * wordSize);
391
392 // return
393 __ vzeroupper();
394 __ pop(rbp);
395 __ ret(0);
396
397 // handle return types different from T_INT
398 __ BIND(is_long);
399 __ movq(Address(c_rarg0, 0), rax);
400 __ jmp(exit);
401
402 __ BIND(is_float);
403 __ movflt(Address(c_rarg0, 0), xmm0);
404 __ jmp(exit);
405
406 __ BIND(is_double);
407 __ movdbl(Address(c_rarg0, 0), xmm0);
408 __ jmp(exit);
409
410 return start;
411 }
412
413 // Return point for a Java call if there's an exception thrown in
414 // Java code. The exception is caught and transformed into a
415 // pending exception stored in JavaThread that can be tested from
416 // within the VM.
417 //
418 // Note: Usually the parameters are removed by the callee. In case
419 // of an exception crossing an activation frame boundary, that is
420 // not the case if the callee is compiled code => need to setup the
421 // rsp.
422 //
423 // rax: exception oop
424
425 address StubGenerator::generate_catch_exception() {
426 StubCodeMark mark(this, "StubRoutines", "catch_exception");
427 address start = __ pc();
3651 void StubGenerator::create_control_words() {
3652 // Round to nearest, 64-bit mode, exceptions masked
3653 StubRoutines::x86::_mxcsr_std = 0x1F80;
3654 }
3655
3656 // Initialization
3657 void StubGenerator::generate_initial() {
3658 // Generates all stubs and initializes the entry points
3659
3660 // This platform-specific settings are needed by generate_call_stub()
3661 create_control_words();
3662
3663 // entry points that exist in all platforms Note: This is code
3664 // that could be shared among different platforms - however the
3665 // benefit seems to be smaller than the disadvantage of having a
3666 // much more complicated generator structure. See also comment in
3667 // stubRoutines.hpp.
3668
3669 StubRoutines::_forward_exception_entry = generate_forward_exception();
3670
3671 StubRoutines::_call_stub_entry =
3672 generate_call_stub(StubRoutines::_call_stub_return_address);
3673
3674 // is referenced by megamorphic call
3675 StubRoutines::_catch_exception_entry = generate_catch_exception();
3676
3677 // atomic calls
3678 StubRoutines::_fence_entry = generate_orderaccess_fence();
3679
3680 // platform dependent
3681 StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
3682
3683 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
3684
3685 StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
3686 StubRoutines::x86::_f2l_fixup = generate_f2l_fixup();
3687 StubRoutines::x86::_d2i_fixup = generate_d2i_fixup();
3688 StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
3689
3690 StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF);
3710 }
3711
3712 if (UsePoly1305Intrinsics) {
3713 StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks();
3714 }
3715
3716 if (UseCRC32CIntrinsics) {
3717 bool supports_clmul = VM_Version::supports_clmul();
3718 StubRoutines::x86::generate_CRC32C_table(supports_clmul);
3719 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
3720 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
3721 }
3722
3723 if (UseAdler32Intrinsics) {
3724 StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
3725 }
3726
3727 generate_libm_stubs();
3728 }
3729
3730 void StubGenerator::generate_phase1() {
3731 // Continuation stubs:
3732 StubRoutines::_cont_thaw = generate_cont_thaw();
3733 StubRoutines::_cont_returnBarrier = generate_cont_returnBarrier();
3734 StubRoutines::_cont_returnBarrierExc = generate_cont_returnBarrier_exception();
3735
3736 JFR_ONLY(StubRoutines::_jfr_write_checkpoint_stub = generate_jfr_write_checkpoint();)
3737 JFR_ONLY(StubRoutines::_jfr_write_checkpoint = StubRoutines::_jfr_write_checkpoint_stub->entry_point();)
3738 }
3739
3740 void StubGenerator::generate_all() {
3741 // Generates all stubs and initializes the entry points
3742
3743 // These entry points require SharedInfo::stack0 to be set up in
3744 // non-core builds and need to be relocatable, so they each
3745 // fabricate a RuntimeStub internally.
3746 StubRoutines::_throw_AbstractMethodError_entry =
3747 generate_throw_exception("AbstractMethodError throw_exception",
3748 CAST_FROM_FN_PTR(address,
3749 SharedRuntime::
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/assembler.hpp"
27 #include "asm/macroAssembler.hpp"
28 #include "classfile/vmIntrinsics.hpp"
29 #include "compiler/oopMap.hpp"
30 #include "gc/shared/barrierSet.hpp"
31 #include "gc/shared/barrierSetAssembler.hpp"
32 #include "gc/shared/barrierSetNMethod.hpp"
33 #include "gc/shared/gc_globals.hpp"
34 #include "memory/universe.hpp"
35 #include "prims/jvmtiExport.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/javaThread.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubRoutines.hpp"
40 #include "utilities/macros.hpp"
41 #include "vmreg_x86.inline.hpp"
42 #include "stubGenerator_x86_64.hpp"
43 #ifdef COMPILER2
44 #include "opto/runtime.hpp"
45 #include "opto/c2_globals.hpp"
46 #endif
47 #if INCLUDE_JVMCI
48 #include "jvmci/jvmci_globals.hpp"
49 #endif
50 #if INCLUDE_ZGC
51 #include "gc/z/zThreadLocalData.hpp"
52 #endif
53 #if INCLUDE_JFR
54 #include "jfr/support/jfrIntrinsics.hpp"
55 #endif
56
57 // For a more detailed description of the stub routine structure
58 // see the comment in stubRoutines.hpp
59
60 #define __ _masm->
61 #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
303 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1
304 __ BIND(loop);
305 __ movptr(rax, Address(c_rarg2, 0));// get parameter
306 __ addptr(c_rarg2, wordSize); // advance to next parameter
307 __ decrementl(c_rarg1); // decrement counter
308 __ push(rax); // pass parameter
309 __ jcc(Assembler::notZero, loop);
310
311 // call Java function
312 __ BIND(parameters_done);
313 __ movptr(rbx, method); // get Method*
314 __ movptr(c_rarg1, entry_point); // get entry_point
315 __ mov(r13, rsp); // set sender sp
316 BLOCK_COMMENT("call Java function");
317 __ call(c_rarg1);
318
319 BLOCK_COMMENT("call_stub_return_address:");
320 return_address = __ pc();
321
322 // store result depending on type (everything that is not
323 // T_OBJECT, T_PRIMITIVE_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
324 __ movptr(r13, result);
325 Label is_long, is_float, is_double, check_prim, exit;
326 __ movl(rbx, result_type);
327 __ cmpl(rbx, T_OBJECT);
328 __ jcc(Assembler::equal, check_prim);
329 __ cmpl(rbx, T_PRIMITIVE_OBJECT);
330 __ jcc(Assembler::equal, check_prim);
331 __ cmpl(rbx, T_LONG);
332 __ jcc(Assembler::equal, is_long);
333 __ cmpl(rbx, T_FLOAT);
334 __ jcc(Assembler::equal, is_float);
335 __ cmpl(rbx, T_DOUBLE);
336 __ jcc(Assembler::equal, is_double);
337
338 // handle T_INT case
339 __ movl(Address(r13, 0), rax);
340
341 __ BIND(exit);
342
343 // pop parameters
344 __ lea(rsp, rsp_after_call);
345
346 #ifdef ASSERT
347 // verify that threads correspond
348 {
349 Label L1, L2, L3;
350 __ cmpptr(r15_thread, thread);
351 __ jcc(Assembler::equal, L1);
352 __ stop("StubRoutines::call_stub: r15_thread is corrupted");
353 __ bind(L1);
354 __ get_thread(rbx);
355 __ cmpptr(r15_thread, thread);
356 __ jcc(Assembler::equal, L2);
357 __ stop("StubRoutines::call_stub: r15_thread is modified by call");
358 __ bind(L2);
359 __ cmpptr(r15_thread, rbx);
383 __ movptr(r13, r13_save);
384 __ movptr(r12, r12_save);
385 __ movptr(rbx, rbx_save);
386
387 #ifdef _WIN64
388 __ movptr(rdi, rdi_save);
389 __ movptr(rsi, rsi_save);
390 #else
391 __ ldmxcsr(mxcsr_save);
392 #endif
393
394 // restore rsp
395 __ addptr(rsp, -rsp_after_call_off * wordSize);
396
397 // return
398 __ vzeroupper();
399 __ pop(rbp);
400 __ ret(0);
401
402 // handle return types different from T_INT
403 __ BIND(check_prim);
404 if (InlineTypeReturnedAsFields) {
405 // Check for scalarized return value
406 __ testptr(rax, 1);
407 __ jcc(Assembler::zero, is_long);
408 // Load pack handler address
409 __ andptr(rax, -2);
410 __ movptr(rax, Address(rax, InstanceKlass::adr_inlineklass_fixed_block_offset()));
411 __ movptr(rbx, Address(rax, InlineKlass::pack_handler_jobject_offset()));
412 // Call pack handler to initialize the buffer
413 __ call(rbx);
414 __ jmp(exit);
415 }
416 __ BIND(is_long);
417 __ movq(Address(r13, 0), rax);
418 __ jmp(exit);
419
420 __ BIND(is_float);
421 __ movflt(Address(r13, 0), xmm0);
422 __ jmp(exit);
423
424 __ BIND(is_double);
425 __ movdbl(Address(r13, 0), xmm0);
426 __ jmp(exit);
427
428 return start;
429 }
430
431 // Return point for a Java call if there's an exception thrown in
432 // Java code. The exception is caught and transformed into a
433 // pending exception stored in JavaThread that can be tested from
434 // within the VM.
435 //
436 // Note: Usually the parameters are removed by the callee. In case
437 // of an exception crossing an activation frame boundary, that is
438 // not the case if the callee is compiled code => need to setup the
439 // rsp.
440 //
441 // rax: exception oop
442
443 address StubGenerator::generate_catch_exception() {
444 StubCodeMark mark(this, "StubRoutines", "catch_exception");
445 address start = __ pc();
3669 void StubGenerator::create_control_words() {
3670 // Round to nearest, 64-bit mode, exceptions masked
3671 StubRoutines::x86::_mxcsr_std = 0x1F80;
3672 }
3673
3674 // Initialization
3675 void StubGenerator::generate_initial() {
3676 // Generates all stubs and initializes the entry points
3677
3678 // This platform-specific settings are needed by generate_call_stub()
3679 create_control_words();
3680
3681 // entry points that exist in all platforms Note: This is code
3682 // that could be shared among different platforms - however the
3683 // benefit seems to be smaller than the disadvantage of having a
3684 // much more complicated generator structure. See also comment in
3685 // stubRoutines.hpp.
3686
3687 StubRoutines::_forward_exception_entry = generate_forward_exception();
3688
3689 // Generate these first because they are called from other stubs
3690 if (InlineTypeReturnedAsFields) {
3691 StubRoutines::_load_inline_type_fields_in_regs =
3692 generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::load_inline_type_fields_in_regs),
3693 "load_inline_type_fields_in_regs", false);
3694 StubRoutines::_store_inline_type_fields_to_buf =
3695 generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::store_inline_type_fields_to_buf),
3696 "store_inline_type_fields_to_buf", true);
3697 }
3698
3699 StubRoutines::_call_stub_entry =
3700 generate_call_stub(StubRoutines::_call_stub_return_address);
3701
3702 // is referenced by megamorphic call
3703 StubRoutines::_catch_exception_entry = generate_catch_exception();
3704
3705 // atomic calls
3706 StubRoutines::_fence_entry = generate_orderaccess_fence();
3707
3708 // platform dependent
3709 StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
3710
3711 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
3712
3713 StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
3714 StubRoutines::x86::_f2l_fixup = generate_f2l_fixup();
3715 StubRoutines::x86::_d2i_fixup = generate_d2i_fixup();
3716 StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
3717
3718 StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF);
3738 }
3739
3740 if (UsePoly1305Intrinsics) {
3741 StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks();
3742 }
3743
3744 if (UseCRC32CIntrinsics) {
3745 bool supports_clmul = VM_Version::supports_clmul();
3746 StubRoutines::x86::generate_CRC32C_table(supports_clmul);
3747 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
3748 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
3749 }
3750
3751 if (UseAdler32Intrinsics) {
3752 StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
3753 }
3754
3755 generate_libm_stubs();
3756 }
3757
3758 // Call here from the interpreter or compiled code to either load
3759 // multiple returned values from the inline type instance being
3760 // returned to registers or to store returned values to a newly
3761 // allocated inline type instance.
3762 // Register is a class, but it would be assigned numerical value.
3763 // "0" is assigned for xmm0. Thus we need to ignore -Wnonnull.
3764 PRAGMA_DIAG_PUSH
3765 PRAGMA_NONNULL_IGNORED
3766 address StubGenerator::generate_return_value_stub(address destination, const char* name, bool has_res) {
3767 // We need to save all registers the calling convention may use so
3768 // the runtime calls read or update those registers. This needs to
3769 // be in sync with SharedRuntime::java_return_convention().
3770 enum layout {
3771 pad_off = frame::arg_reg_save_area_bytes/BytesPerInt, pad_off_2,
3772 rax_off, rax_off_2,
3773 j_rarg5_off, j_rarg5_2,
3774 j_rarg4_off, j_rarg4_2,
3775 j_rarg3_off, j_rarg3_2,
3776 j_rarg2_off, j_rarg2_2,
3777 j_rarg1_off, j_rarg1_2,
3778 j_rarg0_off, j_rarg0_2,
3779 j_farg0_off, j_farg0_2,
3780 j_farg1_off, j_farg1_2,
3781 j_farg2_off, j_farg2_2,
3782 j_farg3_off, j_farg3_2,
3783 j_farg4_off, j_farg4_2,
3784 j_farg5_off, j_farg5_2,
3785 j_farg6_off, j_farg6_2,
3786 j_farg7_off, j_farg7_2,
3787 rbp_off, rbp_off_2,
3788 return_off, return_off_2,
3789
3790 framesize
3791 };
3792
3793 CodeBuffer buffer(name, 1000, 512);
3794 MacroAssembler* _masm = new MacroAssembler(&buffer);
3795
3796 int frame_size_in_bytes = align_up(framesize*BytesPerInt, 16);
3797 assert(frame_size_in_bytes == framesize*BytesPerInt, "misaligned");
3798 int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
3799 int frame_size_in_words = frame_size_in_bytes / wordSize;
3800
3801 OopMapSet *oop_maps = new OopMapSet();
3802 OopMap* map = new OopMap(frame_size_in_slots, 0);
3803
3804 map->set_callee_saved(VMRegImpl::stack2reg(rax_off), rax->as_VMReg());
3805 map->set_callee_saved(VMRegImpl::stack2reg(j_rarg5_off), j_rarg5->as_VMReg());
3806 map->set_callee_saved(VMRegImpl::stack2reg(j_rarg4_off), j_rarg4->as_VMReg());
3807 map->set_callee_saved(VMRegImpl::stack2reg(j_rarg3_off), j_rarg3->as_VMReg());
3808 map->set_callee_saved(VMRegImpl::stack2reg(j_rarg2_off), j_rarg2->as_VMReg());
3809 map->set_callee_saved(VMRegImpl::stack2reg(j_rarg1_off), j_rarg1->as_VMReg());
3810 map->set_callee_saved(VMRegImpl::stack2reg(j_rarg0_off), j_rarg0->as_VMReg());
3811 map->set_callee_saved(VMRegImpl::stack2reg(j_farg0_off), j_farg0->as_VMReg());
3812 map->set_callee_saved(VMRegImpl::stack2reg(j_farg1_off), j_farg1->as_VMReg());
3813 map->set_callee_saved(VMRegImpl::stack2reg(j_farg2_off), j_farg2->as_VMReg());
3814 map->set_callee_saved(VMRegImpl::stack2reg(j_farg3_off), j_farg3->as_VMReg());
3815 map->set_callee_saved(VMRegImpl::stack2reg(j_farg4_off), j_farg4->as_VMReg());
3816 map->set_callee_saved(VMRegImpl::stack2reg(j_farg5_off), j_farg5->as_VMReg());
3817 map->set_callee_saved(VMRegImpl::stack2reg(j_farg6_off), j_farg6->as_VMReg());
3818 map->set_callee_saved(VMRegImpl::stack2reg(j_farg7_off), j_farg7->as_VMReg());
3819
3820 int start = __ offset();
3821
3822 __ subptr(rsp, frame_size_in_bytes - 8 /* return address*/);
3823
3824 __ movptr(Address(rsp, rbp_off * BytesPerInt), rbp);
3825 __ movdbl(Address(rsp, j_farg7_off * BytesPerInt), j_farg7);
3826 __ movdbl(Address(rsp, j_farg6_off * BytesPerInt), j_farg6);
3827 __ movdbl(Address(rsp, j_farg5_off * BytesPerInt), j_farg5);
3828 __ movdbl(Address(rsp, j_farg4_off * BytesPerInt), j_farg4);
3829 __ movdbl(Address(rsp, j_farg3_off * BytesPerInt), j_farg3);
3830 __ movdbl(Address(rsp, j_farg2_off * BytesPerInt), j_farg2);
3831 __ movdbl(Address(rsp, j_farg1_off * BytesPerInt), j_farg1);
3832 __ movdbl(Address(rsp, j_farg0_off * BytesPerInt), j_farg0);
3833
3834 __ movptr(Address(rsp, j_rarg0_off * BytesPerInt), j_rarg0);
3835 __ movptr(Address(rsp, j_rarg1_off * BytesPerInt), j_rarg1);
3836 __ movptr(Address(rsp, j_rarg2_off * BytesPerInt), j_rarg2);
3837 __ movptr(Address(rsp, j_rarg3_off * BytesPerInt), j_rarg3);
3838 __ movptr(Address(rsp, j_rarg4_off * BytesPerInt), j_rarg4);
3839 __ movptr(Address(rsp, j_rarg5_off * BytesPerInt), j_rarg5);
3840 __ movptr(Address(rsp, rax_off * BytesPerInt), rax);
3841
3842 int frame_complete = __ offset();
3843
3844 __ set_last_Java_frame(noreg, noreg, NULL, rscratch1);
3845
3846 __ mov(c_rarg0, r15_thread);
3847 __ mov(c_rarg1, rax);
3848
3849 __ call(RuntimeAddress(destination));
3850
3851 // Set an oopmap for the call site.
3852
3853 oop_maps->add_gc_map( __ offset() - start, map);
3854
3855 // clear last_Java_sp
3856 __ reset_last_Java_frame(false);
3857
3858 __ movptr(rbp, Address(rsp, rbp_off * BytesPerInt));
3859 __ movdbl(j_farg7, Address(rsp, j_farg7_off * BytesPerInt));
3860 __ movdbl(j_farg6, Address(rsp, j_farg6_off * BytesPerInt));
3861 __ movdbl(j_farg5, Address(rsp, j_farg5_off * BytesPerInt));
3862 __ movdbl(j_farg4, Address(rsp, j_farg4_off * BytesPerInt));
3863 __ movdbl(j_farg3, Address(rsp, j_farg3_off * BytesPerInt));
3864 __ movdbl(j_farg2, Address(rsp, j_farg2_off * BytesPerInt));
3865 __ movdbl(j_farg1, Address(rsp, j_farg1_off * BytesPerInt));
3866 __ movdbl(j_farg0, Address(rsp, j_farg0_off * BytesPerInt));
3867
3868 __ movptr(j_rarg0, Address(rsp, j_rarg0_off * BytesPerInt));
3869 __ movptr(j_rarg1, Address(rsp, j_rarg1_off * BytesPerInt));
3870 __ movptr(j_rarg2, Address(rsp, j_rarg2_off * BytesPerInt));
3871 __ movptr(j_rarg3, Address(rsp, j_rarg3_off * BytesPerInt));
3872 __ movptr(j_rarg4, Address(rsp, j_rarg4_off * BytesPerInt));
3873 __ movptr(j_rarg5, Address(rsp, j_rarg5_off * BytesPerInt));
3874 __ movptr(rax, Address(rsp, rax_off * BytesPerInt));
3875
3876 __ addptr(rsp, frame_size_in_bytes-8);
3877
3878 // check for pending exceptions
3879 Label pending;
3880 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
3881 __ jcc(Assembler::notEqual, pending);
3882
3883 if (has_res) {
3884 __ get_vm_result(rax, r15_thread);
3885 }
3886
3887 __ ret(0);
3888
3889 __ bind(pending);
3890
3891 __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
3892 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3893
3894 // -------------
3895 // make sure all code is generated
3896 _masm->flush();
3897
3898 RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, false);
3899 return stub->entry_point();
3900 }
3901
3902 void StubGenerator::generate_phase1() {
3903 // Continuation stubs:
3904 StubRoutines::_cont_thaw = generate_cont_thaw();
3905 StubRoutines::_cont_returnBarrier = generate_cont_returnBarrier();
3906 StubRoutines::_cont_returnBarrierExc = generate_cont_returnBarrier_exception();
3907
3908 JFR_ONLY(StubRoutines::_jfr_write_checkpoint_stub = generate_jfr_write_checkpoint();)
3909 JFR_ONLY(StubRoutines::_jfr_write_checkpoint = StubRoutines::_jfr_write_checkpoint_stub->entry_point();)
3910 }
3911
3912 void StubGenerator::generate_all() {
3913 // Generates all stubs and initializes the entry points
3914
3915 // These entry points require SharedInfo::stack0 to be set up in
3916 // non-core builds and need to be relocatable, so they each
3917 // fabricate a RuntimeStub internally.
3918 StubRoutines::_throw_AbstractMethodError_entry =
3919 generate_throw_exception("AbstractMethodError throw_exception",
3920 CAST_FROM_FN_PTR(address,
3921 SharedRuntime::
|