src/hotspot/cpu/x86/stubGenerator_x86_32.cpp
changeset 59284 88502b1cf76f
parent 59251 4cbfa5077d68
equal deleted inserted replaced
59283:78aa7484c722 59284:88502b1cf76f
    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) {