@@ -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