diff options
| author | Aaron Patterson <tenderlove@ruby-lang.org> | 2024-04-24 15:42:40 -0700 |
|---|---|---|
| committer | Aaron Patterson <aaron.patterson@gmail.com> | 2024-06-18 09:28:25 -0700 |
| commit | bd7a87e5bbe8dca6414d1bb719e945dec80dd311 (patch) | |
| tree | 7972240847952392e83f1c2c42576bea7bf14d4e | |
| parent | cdf33ed5f37f9649c482c3ba1d245f0d80ac01ce (diff) | |
Add a CC fastpath for forwardable methods
| -rw-r--r-- | vm_insnhelper.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index a74f5096f6..7c225a8c3d 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2917,6 +2917,26 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons VALUE *const locals); static VALUE +vm_call_iseq_forwardable(rb_execution_context_t *ec, rb_control_frame_t *cfp, + struct rb_calling_info *calling) +{ + const struct rb_callcache *cc = calling->cc; + const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def); + int param_size = ISEQ_BODY(iseq)->param.size; + int local_size = ISEQ_BODY(iseq)->local_table_size; + + // Setting up local size and param size + VM_ASSERT(ISEQ_BODY(iseq)->param.flags.forwardable); + + local_size = local_size + vm_ci_argc(calling->cd->ci); + param_size = param_size + vm_ci_argc(calling->cd->ci); + + cfp->sp[0] = (VALUE)calling->cd->ci; + + return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), 0, param_size, local_size); +} + +static VALUE vm_call_iseq_setup_kwparm_kwarg(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling) { @@ -3171,6 +3191,8 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling, // => type // if (ISEQ_BODY(iseq)->param.flags.forwardable) { + bool can_fastpath = true; + if ((vm_ci_flag(ci) & VM_CALL_FORWARDING)) { struct rb_forwarding_call_data * forward_cd = (struct rb_forwarding_call_data *)calling->cd; if (vm_ci_argc(ci) != vm_ci_argc(forward_cd->caller_ci)) { @@ -3182,6 +3204,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling, } else { ci = forward_cd->caller_ci; } + can_fastpath = false; } // C functions calling iseqs will stack allocate a CI, // so we need to convert it to heap allocated @@ -3191,8 +3214,10 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling, vm_ci_flag(ci), vm_ci_argc(ci), vm_ci_kwarg(ci)); + can_fastpath = false; } argv[param_size - 1] = (VALUE)ci; + CC_SET_FASTPATH(cc, vm_call_iseq_forwardable, can_fastpath); return 0; } |
