diff options
author | Takashi Kokubun <[email protected]> | 2023-11-30 18:35:55 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2023-11-30 21:35:55 -0500 |
commit | ba1cdadfc8ad6f284efeefbcebef1ca85bae178c (patch) | |
tree | c9ea54db14ca957a0df99487b9be19c368908dca /cont.c | |
parent | 5888a16a125e573c1749000b343d41db76289c15 (diff) |
YJIT: Cancel on-stack jit_return on invalidation (#9086)
* YJIT: Cancel on-stack jit_return on invalidation
Co-authored-by: Alan Wu <[email protected]>
* Use RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P
---------
Co-authored-by: Alan Wu <[email protected]>
Diffstat (limited to 'cont.c')
-rw-r--r-- | cont.c | 33 |
1 files changed, 26 insertions, 7 deletions
@@ -1290,18 +1290,37 @@ rb_jit_cont_each_iseq(rb_iseq_callback callback, void *data) if (cont->ec->vm_stack == NULL) continue; - const rb_control_frame_t *cfp; - for (cfp = RUBY_VM_END_CONTROL_FRAME(cont->ec) - 1; ; cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp)) { - const rb_iseq_t *iseq; - if (cfp->pc && (iseq = cfp->iseq) != NULL && imemo_type((VALUE)iseq) == imemo_iseq) { - callback(iseq, data); + const rb_control_frame_t *cfp = cont->ec->cfp; + while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) { + if (cfp->pc && cfp->iseq && imemo_type((VALUE)cfp->iseq) == imemo_iseq) { + callback(cfp->iseq, data); } + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + } + } +} + +#if USE_YJIT +// Update the jit_return of all CFPs to leave_exit unless it's leave_exception or not set. +// This prevents jit_exec_exception from jumping to the caller after invalidation. +void +rb_yjit_cancel_jit_return(void *leave_exit, void *leave_exception) +{ + struct rb_jit_cont *cont; + for (cont = first_jit_cont; cont != NULL; cont = cont->next) { + if (cont->ec->vm_stack == NULL) + continue; - if (cfp == cont->ec->cfp) - break; // reached the most recent cfp + const rb_control_frame_t *cfp = cont->ec->cfp; + while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) { + if (cfp->jit_return && cfp->jit_return != leave_exception) { + ((rb_control_frame_t *)cfp)->jit_return = leave_exit; + } + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } } } +#endif // Finish working with jit_cont. void |