Skip to content

Commit 551ee85

Browse files
committed
templateInterpreterGenerator_s390 finished
1 parent 4495a71 commit 551ee85

File tree

5 files changed

+48
-6
lines changed

5 files changed

+48
-6
lines changed

src/hotspot/cpu/s390/interp_masm_s390.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ void InterpreterMacroAssembler::call_VM_preemptable(Register oop_result, address
211211
}
212212

213213
void InterpreterMacroAssembler::restore_after_resume(Register fp) {
214+
// TODO: What's the use of "fp" register coming as an argument ?
214215
if (!Continuations::enabled()) return;
215216
load_const_optimized(Z_R1, Interpreter::cont_resume_interpreter_adapter());
216217
call(Z_R1);

src/hotspot/cpu/s390/interp_masm_s390.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
5050
Label *last_java_pc);
5151

5252
void call_VM_preemptable(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true);
53-
void restore_after_resume(Register fp);
5453

5554
// Base routine for all dispatches.
5655
void dispatch_base(TosState state, address* table, bool generate_poll = false);
@@ -59,6 +58,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
5958
InterpreterMacroAssembler(CodeBuffer* c)
6059
: MacroAssembler(c) {}
6160

61+
void restore_after_resume(Register fp);
6262
virtual void check_and_handle_popframe(Register java_thread);
6363
virtual void check_and_handle_earlyret(Register java_thread);
6464

src/hotspot/cpu/s390/macroAssembler_s390.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ class MacroAssembler: public Assembler {
812812
inline void set_last_Java_frame_static(Register last_java_sp, Register last_Java_pc);
813813
inline void reset_last_Java_frame(void);
814814
inline void reset_last_Java_frame_static(void);
815-
inline void set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, Register tmp1);
815+
inline void set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, Register tmp1, Label* jpc = nullptr);
816816
inline void set_top_ijava_frame_at_SP_as_last_Java_frame_static(Register sp, Register tmp1);
817817

818818
void set_thread_state(JavaThreadState new_state);

src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ inline void MacroAssembler::reset_last_Java_frame_static(void) {
303303
reset_last_Java_frame(false);
304304
}
305305

306-
inline void MacroAssembler::set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, Register tmp1) {
307-
set_top_ijava_frame_at_SP_as_last_Java_frame(sp, tmp1, true);
306+
inline void MacroAssembler::set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, Register tmp1, Label *jpc) {
307+
set_top_ijava_frame_at_SP_as_last_Java_frame(sp, tmp1, true, jpc);
308308
}
309309

310310
inline void MacroAssembler::set_top_ijava_frame_at_SP_as_last_Java_frame_static(Register sp, Register tmp1) {

src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,8 +1487,13 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
14871487

14881488
__ bind(call_signature_handler);
14891489

1490+
bool support_vthread_preemption = Continuations::enabled();
1491+
14901492
// We have a TOP_IJAVA_FRAME here, which belongs to us.
1491-
__ set_top_ijava_frame_at_SP_as_last_Java_frame(Z_SP, Z_R1/*tmp*/);
1493+
Label last_java_pc;
1494+
Label *resume_pc = support_vthread_preemption ? &last_java_pc : nullptr;
1495+
1496+
__ set_top_ijava_frame_at_SP_as_last_Java_frame(Z_SP, Z_R1/*tmp*/, resume_pc);
14921497

14931498
// Call signature handler and pass locals address in Z_ARG1.
14941499
__ z_lgr(Z_ARG1, Z_locals);
@@ -1545,7 +1550,17 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
15451550
// overwritten since "__ call_stub(signature_handler);" (except for
15461551
// ARG1 and ARG2 for static methods).
15471552

1548-
// TODO: https://bugs.openjdk.org/browse/JDK-8338383
1553+
if (support_vthread_preemption) {
1554+
// Rresult_handler is a nonvolatile register. Its value will be preserved across
1555+
// the native call but only if the call isn't preempted. To preserve its value even
1556+
// in the case of preemption we save it in the lresult slot. It is restored at
1557+
// resume_pc if, and only if the call was preempted. This works because only
1558+
// j.l.Object::wait calls are preempted which don't return a result.
1559+
1560+
// TODO: are we sure this is Z_fp and not Z_SP
1561+
// TODO: are we sure this will survive till here ?
1562+
__ z_stg(Rresult_handler, _z_ijava_state_neg(lresult), Z_fp);
1563+
}
15491564
__ push_cont_fastpath();
15501565
__ call_c(Z_R1/*native_method_entry*/);
15511566
__ pop_cont_fastpath();
@@ -1632,6 +1647,32 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
16321647
__ z_lg(Z_bcp, Address(Rmethod, Method::const_offset())); // get constMethod
16331648
__ add2reg(Z_bcp, in_bytes(ConstMethod::codes_offset())); // get codebase
16341649

1650+
if (support_vthread_preemption) {
1651+
// Check preemption for Object.wait()
1652+
Label not_preempted;
1653+
__ z_ltg(Z_R1_scratch, Address(Z_thread, JavaThread::preempt_alternate_return_offset()));
1654+
__ z_brz(not_preempted); // if 0, jump to not_preempted
1655+
__ z_mvghi(Address(Z_thread, JavaThread::preempt_alternate_return_offset()), 0);
1656+
__ call(Z_R1);
1657+
1658+
// Execution will be resumed here when the vthread becomes runnable again.
1659+
__ bind(*resume_pc);
1660+
__ restore_after_resume(Z_fp /* fp */);
1661+
// We saved the result handler before the call
1662+
__ z_lg(Rresult_handler, _z_ijava_state_neg(lresult), Z_fp);
1663+
#ifdef ASSERT
1664+
// Clobber result slots. Only native methods returning void can be preemted currently.
1665+
__ load_const(Z_RET, UCONST64(0xbad01001));
1666+
__ z_stg(Z_RET, _z_ijava_state_neg(lresult), Z_fp);
1667+
__ z_stg(Z_RET, _z_ijava_state_neg(fresult), Z_fp);
1668+
// reset_last_Java_frame() below asserts that a last java sp is set
1669+
__ asm_assert_mem8_is_zero(in_bytes(JavaThread::last_Java_sp_offset()),
1670+
Z_thread, FILE_AND_LINE ": Last java sp should not be set when resuming", 69);
1671+
__ z_stg(Z_RET, in_bytes(JavaThread::last_Java_sp_offset()), Z_thread);
1672+
#endif
1673+
__ bind(not_preempted);
1674+
}
1675+
16351676
if (CheckJNICalls) {
16361677
// clear_pending_jni_exception_check
16371678
__ clear_mem(Address(Z_thread, JavaThread::pending_jni_exception_check_fn_offset()), sizeof(oop));

0 commit comments

Comments
 (0)