diff options
author | Takashi Kokubun <[email protected]> | 2024-11-04 08:14:28 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2024-11-04 11:14:28 -0500 |
commit | 478e0fc710b8fefaa3bdb7cb41dda8716e29927a (patch) | |
tree | 7e4dfe65ad53e2ae5483adb0276d00ebe58bb802 /vm_backtrace.c | |
parent | 51ac93011a8b279c1e2b93bbe6c8709392e82f57 (diff) |
YJIT: Replace Array#each only when YJIT is enabled (#11955)
* YJIT: Replace Array#each only when YJIT is enabled
* Add comments about BUILTIN_ATTR_C_TRACE
* Make Ruby Array#each available with --yjit as well
* Fix all paths that expect a C location
* Use method_basic_definition_p to detect patches
* Copy a comment about C_TRACE flag to compilers
* Rephrase a comment about add_yjit_hook
* Give METHOD_ENTRY_BASIC flag to Array#each
* Add --yjit-c-builtin option
* Allow inconsistent source_location in test-spec
* Refactor a check of BUILTIN_ATTR_C_TRACE
* Set METHOD_ENTRY_BASIC without touching vm->running
Notes
Notes:
Merged-By: maximecb <[email protected]>
Diffstat (limited to 'vm_backtrace.c')
-rw-r--r-- | vm_backtrace.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/vm_backtrace.c b/vm_backtrace.c index 22b28368d7..56a0d861d6 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -265,10 +265,26 @@ retry: } } +// Return true if a given location is a C method or supposed to behave like one. +static inline bool +location_cfunc_p(rb_backtrace_location_t *loc) +{ + if (!loc->cme) return false; + + switch (loc->cme->def->type) { + case VM_METHOD_TYPE_CFUNC: + return true; + case VM_METHOD_TYPE_ISEQ: + return rb_iseq_attr_p(loc->cme->def->body.iseq.iseqptr, BUILTIN_ATTR_C_TRACE); + default: + return false; + } +} + static VALUE location_label(rb_backtrace_location_t *loc) { - if (loc->cme && loc->cme->def->type == VM_METHOD_TYPE_CFUNC) { + if (location_cfunc_p(loc)) { return rb_gen_method_name(loc->cme->owner, rb_id2str(loc->cme->def->original_id)); } else { @@ -314,7 +330,7 @@ location_label_m(VALUE self) static VALUE location_base_label(rb_backtrace_location_t *loc) { - if (loc->cme && loc->cme->def->type == VM_METHOD_TYPE_CFUNC) { + if (location_cfunc_p(loc)) { return rb_id2str(loc->cme->def->original_id); } @@ -448,7 +464,7 @@ location_to_str(rb_backtrace_location_t *loc) VALUE file, owner = Qnil, name; int lineno; - if (loc->cme && loc->cme->def->type == VM_METHOD_TYPE_CFUNC) { + if (location_cfunc_p(loc)) { if (loc->iseq && loc->pc) { file = rb_iseq_path(loc->iseq); lineno = calc_lineno(loc->iseq, loc->pc); @@ -684,13 +700,21 @@ rb_ec_partial_backtrace_object(const rb_execution_context_t *ec, long start_fram const VALUE *pc = cfp->pc; loc = &bt->backtrace[bt->backtrace_size++]; RB_OBJ_WRITE(btobj, &loc->cme, rb_vm_frame_method_entry(cfp)); - RB_OBJ_WRITE(btobj, &loc->iseq, iseq); - loc->pc = pc; - bt_update_cfunc_loc(cfunc_counter, loc-1, iseq, pc); - if (do_yield) { - bt_yield_loc(loc - cfunc_counter, cfunc_counter+1, btobj); + // Ruby methods with `Primitive.attr! :c_trace` should behave like C methods + if (rb_iseq_attr_p(cfp->iseq, BUILTIN_ATTR_C_TRACE)) { + loc->iseq = NULL; + loc->pc = NULL; + cfunc_counter++; + } + else { + RB_OBJ_WRITE(btobj, &loc->iseq, iseq); + loc->pc = pc; + bt_update_cfunc_loc(cfunc_counter, loc-1, iseq, pc); + if (do_yield) { + bt_yield_loc(loc - cfunc_counter, cfunc_counter+1, btobj); + } + cfunc_counter = 0; } - cfunc_counter = 0; } skip_next_frame = is_rescue_or_ensure_frame(cfp); } |