diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index aa3d4849062..f62051c628e 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -575,11 +575,17 @@ void InterpreterMacroAssembler::store_ptr(int n, Register val) { void InterpreterMacroAssembler::prepare_to_jump_from_interpreted(Register method) { // Satisfy interpreter calling convention (see generate_normal_entry()). z_lgr(Z_R10, Z_SP); // Set sender sp (aka initial caller sp, aka unextended sp). - // Record top_frame_sp, because the callee might modify it, if it's compiled. - assert_different_registers(Z_R1, method); - z_sgrk(Z_R1, Z_SP, Z_fp); - z_srag(Z_R1, Z_R1, Interpreter::logStackElementSize); - z_stg(Z_R1, _z_ijava_state_neg(top_frame_sp), Z_fp); +#ifdef ASSERT + NearLabel ok; + Register tmp = Z_R1; + z_lg(tmp, Address(Z_fp, _z_ijava_state_neg(top_frame_sp))); + z_slag(tmp, tmp, Interpreter::logStackElementSize); + z_agr(tmp, Z_fp); + z_cgr(tmp, Z_SP); + z_bre(ok); + stop("corrupted top_frame_sp"); + bind(ok); +#endif save_bcp(); save_esp(); z_lgr(Z_method, method); // Set Z_method (kills Z_fp!). @@ -1918,6 +1924,11 @@ void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, // Adjust stack pointer for additional monitor entry. resize_frame(RegisterOrConstant((intptr_t) delta), Z_fp, false); + // Rtemp3 is free at this point, use it to store top_frame_sp + z_sgrk(Rtemp3, Z_SP, Z_fp); + z_srag(Rtemp3, Rtemp3, Interpreter::logStackElementSize); + reg2mem_opt(Rtemp3, Address(Z_fp, _z_ijava_state_neg(top_frame_sp))); + if (!stack_is_empty) { // Must copy stack contents down. NearLabel next, done; diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 3f568572966..2da21f08bbc 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1100,6 +1100,11 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // ... and push the new frame F0. __ push_frame(top_frame_size, fp, true /*copy_sp*/, false); + + __ z_lcgr(top_frame_size); // negate + __ z_srag(top_frame_size, top_frame_size, Interpreter::logStackElementSize); + // Store relativized top_frame_sp + __ z_stg(top_frame_size, _z_ijava_state_neg(top_frame_sp), fp); } //============================================================================= @@ -2068,6 +2073,14 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ z_lg(Z_fp, _z_abi(callers_sp), Z_SP); // Frame accessors use Z_fp. // Z_ARG1 (==Z_tos): exception // Z_ARG2 : Return address/pc that threw exception. + { + Register top_frame_sp = Z_R1_scratch; // anyway going to load it with correct value + __ z_lg(top_frame_sp, Address(Z_fp, _z_ijava_state_neg(top_frame_sp))); + __ z_slag(top_frame_sp, top_frame_sp, Interpreter::logStackElementSize); + __ z_agr(top_frame_sp, Z_fp); + + __ resize_frame_absolute(top_frame_sp, /* temp = */ Z_R0, /* load_fp = */ true); + } __ restore_bcp(); // R13 points to call/send. __ restore_locals(); @@ -2175,6 +2188,14 @@ void TemplateInterpreterGenerator::generate_throw_exception() { false, // install_monitor_exception false); // notify_jvmdi __ z_lg(Z_fp, _z_abi(callers_sp), Z_SP); // Restore frame pointer. + { + Register top_frame_sp = Z_R1_scratch; + __ z_lg(top_frame_sp, Address(Z_fp, _z_ijava_state_neg(top_frame_sp))); + __ z_slag(top_frame_sp, top_frame_sp, Interpreter::logStackElementSize); + __ z_agr(top_frame_sp, Z_fp); + + __ resize_frame_absolute(top_frame_sp, /* temp = */ Z_R0, /* load_fp = */ true); + } __ restore_bcp(); __ restore_locals(); __ restore_esp();