diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 83c59af9113e9..4be408f6ca567 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1184,6 +1184,8 @@ bool is_CAS(int opcode, bool maybe_volatile) } } +constexpr uint64_t MAJIK_DWORD = 0xabbaabbaabbaabbaull; + // predicate controlling translation of CAS // // returns true if CAS needs to use an acquiring load otherwise false @@ -1363,10 +1365,15 @@ void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { st->print("# stack bang size=%d\n\t", framesize); } - st->print("sd fp, [sp, #%d]\n\t", - 2 * wordSize); - st->print("sd ra, [sp, #%d]\n\t", - wordSize); - if (PreserveFramePointer) { st->print("sub fp, sp, #%d\n\t", 2 * wordSize); } st->print("sub sp, sp, #%d\n\t", framesize); + st->print("sd fp, [sp, #%d]\n\t", framesize - 2 * wordSize); + st->print("sd ra, [sp, #%d]\n\t", framesize - wordSize); + if (PreserveFramePointer) { st->print("add fp, sp, #%d\n\t", framesize); } + + if (VerifyStackAtCalls) { + st->print("mv t2, %ld\n\t", MAJIK_DWORD); + st->print("sd t2, [sp, #%d]\n\t", framesize - 3 * wordSize); + } if (C->stub_function() == nullptr) { st->print("ld t0, [guard]\n\t"); @@ -1408,6 +1415,11 @@ void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { __ build_frame(framesize); + if (VerifyStackAtCalls) { + __ mv(t2, MAJIK_DWORD); + __ sd(t2, Address(sp, framesize - 3 * wordSize)); + } + if (C->stub_function() == nullptr) { BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); // Dummy labels for just measuring the code size @@ -1429,10 +1441,6 @@ void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { bs->nmethod_entry_barrier(masm, slow_path, continuation, guard); } - if (VerifyStackAtCalls) { - Unimplemented(); - } - C->output()->set_frame_complete(__ offset()); if (C->has_mach_constant_base_node()) { @@ -2431,7 +2439,13 @@ encode %{ enc_class riscv_enc_call_epilog() %{ if (VerifyStackAtCalls) { // Check that stack depth is unchanged: find majik cookie on stack - __ call_Unimplemented(); + int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3 * VMRegImpl::slots_per_word)); + Label stack_ok; + __ ld(t1, Address(sp, framesize)); + __ mv(t2, MAJIK_DWORD); + __ beq(t2, t1, stack_ok); + __ stop("MAJIK_DWORD not found"); + __ bind(stack_ok); } %} diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index b303178a6666a..e64fc2ffc805e 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -2368,7 +2368,7 @@ void SharedRuntime::generate_deopt_blob() { // EPILOG must remove this many slots. // RISCV needs two words for RA (return address) and FP (frame pointer). uint SharedRuntime::in_preserve_stack_slots() { - return 2 * VMRegImpl::slots_per_word; + return 2 * VMRegImpl::slots_per_word + (VerifyStackAtCalls ? 0 : 2) ; } uint SharedRuntime::out_preserve_stack_slots() { diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 8c8c2b0ed4ee4..524dee6e06a13 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -2408,7 +2408,7 @@ void PhaseChaitin::dump_frame() const { tty->print_cr("saved fp register"); else if (return_addr == OptoReg::add(reg, 2*VMRegImpl::slots_per_word) && VerifyStackAtCalls) - tty->print_cr("0xBADB100D +VerifyStackAtCalls"); + tty->print_cr(" +VerifyStackAtCalls"); else tty->print_cr("in_preserve"); } else if ((int)OptoReg::reg2stack(reg) < fixed_slots) {