25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "asm/macroAssembler.hpp" |
26 #include "asm/macroAssembler.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
28 #include "gc/shared/barrierSet.hpp" |
28 #include "gc/shared/barrierSet.hpp" |
29 #include "gc/shared/barrierSetAssembler.hpp" |
29 #include "gc/shared/barrierSetAssembler.hpp" |
|
30 #include "gc/shared/barrierSetNMethod.hpp" |
30 #include "interpreter/interpreter.hpp" |
31 #include "interpreter/interpreter.hpp" |
31 #include "memory/universe.hpp" |
32 #include "memory/universe.hpp" |
32 #include "nativeInst_x86.hpp" |
33 #include "nativeInst_x86.hpp" |
33 #include "oops/instanceOop.hpp" |
34 #include "oops/instanceOop.hpp" |
34 #include "oops/method.hpp" |
35 #include "oops/method.hpp" |
3661 // Return errValue or *adr. |
3662 // Return errValue or *adr. |
3662 *continuation_pc = __ pc(); |
3663 *continuation_pc = __ pc(); |
3663 __ ret(0); |
3664 __ ret(0); |
3664 } |
3665 } |
3665 |
3666 |
|
3667 address generate_method_entry_barrier() { |
|
3668 __ align(CodeEntryAlignment); |
|
3669 StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); |
|
3670 |
|
3671 Label deoptimize_label; |
|
3672 |
|
3673 address start = __ pc(); |
|
3674 |
|
3675 __ push(-1); // cookie, this is used for writing the new rsp when deoptimizing |
|
3676 |
|
3677 BLOCK_COMMENT("Entry:"); |
|
3678 __ enter(); // save rbp |
|
3679 |
|
3680 // save rbx, because we want to use that value. |
|
3681 // We could do without it but then we depend on the number of slots used by pusha |
|
3682 __ push(rbx); |
|
3683 |
|
3684 __ lea(rbx, Address(rsp, wordSize * 3)); // 1 for cookie, 1 for rbp, 1 for rbx - this should be the return address |
|
3685 |
|
3686 __ pusha(); |
|
3687 |
|
3688 // xmm0 and xmm1 may be used for passing float/double arguments |
|
3689 const int xmm_size = wordSize * 2; |
|
3690 const int xmm_spill_size = xmm_size * 2; |
|
3691 __ subptr(rsp, xmm_spill_size); |
|
3692 __ movdqu(Address(rsp, xmm_size * 1), xmm1); |
|
3693 __ movdqu(Address(rsp, xmm_size * 0), xmm0); |
|
3694 |
|
3695 __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(address*)>(BarrierSetNMethod::nmethod_stub_entry_barrier)), rbx); |
|
3696 |
|
3697 __ movdqu(xmm0, Address(rsp, xmm_size * 0)); |
|
3698 __ movdqu(xmm1, Address(rsp, xmm_size * 1)); |
|
3699 __ addptr(rsp, xmm_spill_size); |
|
3700 |
|
3701 __ cmpl(rax, 1); // 1 means deoptimize |
|
3702 __ jcc(Assembler::equal, deoptimize_label); |
|
3703 |
|
3704 __ popa(); |
|
3705 __ pop(rbx); |
|
3706 |
|
3707 __ leave(); |
|
3708 |
|
3709 __ addptr(rsp, 1 * wordSize); // cookie |
|
3710 __ ret(0); |
|
3711 |
|
3712 __ BIND(deoptimize_label); |
|
3713 |
|
3714 __ popa(); |
|
3715 __ pop(rbx); |
|
3716 |
|
3717 __ leave(); |
|
3718 |
|
3719 // this can be taken out, but is good for verification purposes. getting a SIGSEGV |
|
3720 // here while still having a correct stack is valuable |
|
3721 __ testptr(rsp, Address(rsp, 0)); |
|
3722 |
|
3723 __ movptr(rsp, Address(rsp, 0)); // new rsp was written in the barrier |
|
3724 __ jmp(Address(rsp, -1 * wordSize)); // jmp target should be callers verified_entry_point |
|
3725 |
|
3726 return start; |
|
3727 } |
|
3728 |
3666 public: |
3729 public: |
3667 // Information about frame layout at time of blocking runtime call. |
3730 // Information about frame layout at time of blocking runtime call. |
3668 // Note that we only have to preserve callee-saved registers since |
3731 // Note that we only have to preserve callee-saved registers since |
3669 // the compilers are responsible for supplying a continuation point |
3732 // the compilers are responsible for supplying a continuation point |
3670 // if they expect all registers to be preserved. |
3733 // if they expect all registers to be preserved. |
3957 &StubRoutines::_safefetch32_fault_pc, |
4020 &StubRoutines::_safefetch32_fault_pc, |
3958 &StubRoutines::_safefetch32_continuation_pc); |
4021 &StubRoutines::_safefetch32_continuation_pc); |
3959 StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; |
4022 StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; |
3960 StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; |
4023 StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; |
3961 StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; |
4024 StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; |
|
4025 |
|
4026 BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); |
|
4027 if (bs_nm != NULL) { |
|
4028 StubRoutines::x86::_method_entry_barrier = generate_method_entry_barrier(); |
|
4029 } |
3962 } |
4030 } |
3963 |
4031 |
3964 |
4032 |
3965 public: |
4033 public: |
3966 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { |
4034 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { |