This has been found with the DebugTools tests and the most simple re-producer is:
([3+3] newProcess singleStep; suspend; suspendedContext) inspect. The check for _gst_except_flag is triggerred in the method prologue and the JIT returns to the interpreter loop. When the process is switched an old _gst_ip was written to context->ipOffset. Modify the emit_interrupt_check to take an optional ipOffset parameter that will be stored when the interrupt check triggers. For primitives it is not clear which ipOffset should be saved. 2013-12-23 Holger Hans Peter Freyther <[email protected]> * xlat.c: Add ipOffset parameter to emit_interrupt_check. --- libgst/ChangeLog | 4 ++++ libgst/xlat.c | 24 +++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/libgst/ChangeLog b/libgst/ChangeLog index 4721c17..113a0c3 100644 --- a/libgst/ChangeLog +++ b/libgst/ChangeLog @@ -1,3 +1,7 @@ +2013-12-23 Holger Hans Peter Freyther <[email protected]> + + * xlat.c: Add ipOffset parameter to emit_interrupt_check. + 2014-01-09 Holger Hans Peter Freyther <[email protected]> * prims.def: Mark VMpr_Process_singleStepWaitingOn as diff --git a/libgst/xlat.c b/libgst/xlat.c index 3f4a555..fbae8f7 100644 --- a/libgst/xlat.c +++ b/libgst/xlat.c @@ -332,7 +332,7 @@ static inline mst_Boolean emit_block_prolog (OOP blockOOP, gst_compiled_block bl static inline mst_Boolean emit_inlined_primitive (int primitive, int numArgs, int attr); static inline mst_Boolean emit_primitive (int primitive, int numArgs); -static inline void emit_interrupt_check (int restartReg); +static inline void emit_interrupt_check (int restartReg, int ipOffset); static inline void generate_run_time_code (void); static inline void translate_method (OOP methodOOP, OOP receiverClass, int size); static void emit_basic_size_in_r0 (OOP classOOP, mst_Boolean tagged, int objectReg); @@ -2498,7 +2498,7 @@ emit_deferred_sends (deferred_send *ds) } void -emit_interrupt_check (int restartReg) +emit_interrupt_check (int restartReg, int ipOffset) { jit_insn *jmp, *begin; @@ -2507,9 +2507,17 @@ emit_interrupt_check (int restartReg) jit_ldi_i (JIT_R2, &_gst_except_flag); jmp = jit_beqi_i (jit_forward (), JIT_R2, 0); + + /* Save the global ip pointer */ + if (ipOffset != -1) + { + jit_movi_ul (JIT_R2, ipOffset); + jit_sti_ul (&ip, JIT_R2); + } + + /* Where to restart?*/ if (restartReg == JIT_NOREG) jit_movi_p (JIT_RET, begin); - else jit_movr_p (JIT_RET, restartReg); @@ -2975,7 +2983,7 @@ emit_primitive (int primitive, int numArgs) if (attr & (PRIM_SUCCEED | PRIM_RELOAD_IP)) { if (attr & PRIM_CHECK_INTERRUPT) - emit_interrupt_check (JIT_V2); + emit_interrupt_check (JIT_V2, -1); jit_jmpr (JIT_V2); } @@ -3218,7 +3226,7 @@ emit_method_prolog (OOP methodOOP, emit_context_setup (header.numArgs, header.numTemps); define_ip_map_entry (0); - emit_interrupt_check (JIT_NOREG); + emit_interrupt_check (JIT_NOREG, 0); /* For simplicity, we emit user-defined methods by creating a code_tree for the acrual send of #valueWithReceiver:withArguments: that they do. @@ -3326,7 +3334,7 @@ emit_block_prolog (OOP blockOOP, emit_context_setup (header.numArgs, header.numTemps); define_ip_map_entry (0); - emit_interrupt_check (JIT_NOREG); + emit_interrupt_check (JIT_NOREG, 0); return (false); } @@ -3675,9 +3683,7 @@ translate_method (OOP methodOOP, OOP receiverClass, int size) if (!lbl_define (*this_label)) { define_ip_map_entry (bp - bc); - jit_movi_ul (JIT_V0, bp - bc); - jit_sti_ul (&ip, JIT_V0); - emit_interrupt_check (JIT_NOREG); + emit_interrupt_check (JIT_NOREG, bp - bc); } } -- 1.8.5.2 _______________________________________________ help-smalltalk mailing list [email protected] https://lists.gnu.org/mailman/listinfo/help-smalltalk
