summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <[email protected]>2024-05-24 14:33:03 -0700
committerAaron Patterson <[email protected]>2024-06-18 09:28:25 -0700
commita25dd5b12c550a152d9875720b423e141f36dfb0 (patch)
tree45a035d3c7af749ef9ebf2277b82211d928d289f
parentcfc5646cdc2b693aff1f8b74f30093765df16957 (diff)
Set a fast path for forwardable iseqs
-rw-r--r--vm_eval.c7
-rw-r--r--vm_insnhelper.c34
2 files changed, 34 insertions, 7 deletions
diff --git a/vm_eval.c b/vm_eval.c
index 8da3f3c529..7840ecac4b 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -215,7 +215,12 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
*reg_cfp->sp++ = argv[i];
}
- vm_call_iseq_setup(ec, reg_cfp, calling);
+ if (ISEQ_BODY(def_iseq_ptr(vm_cc_cme(cc)->def))->param.flags.forwardable) {
+ vm_call_iseq_fwd_setup(ec, reg_cfp, calling);
+ }
+ else {
+ vm_call_iseq_setup(ec, reg_cfp, calling);
+ }
VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);
return vm_exec(ec); // CHECK_INTS in this function
}
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 7c225a8c3d..a3352c8b20 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3306,11 +3306,27 @@ vm_call_iseq_setup(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct r
int param_size = ISEQ_BODY(iseq)->param.size;
int local_size = ISEQ_BODY(iseq)->local_table_size;
+ RUBY_ASSERT(!ISEQ_BODY(iseq)->param.flags.forwardable);
+
+ const int opt_pc = vm_callee_setup_arg(ec, calling, iseq, cfp->sp - calling->argc, param_size, local_size);
+ return vm_call_iseq_setup_2(ec, cfp, calling, opt_pc, param_size, local_size);
+}
+
+static VALUE
+vm_call_iseq_fwd_setup(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
+{
+ RB_DEBUG_COUNTER_INC(ccf_iseq_setup);
+
+ 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;
+
+ RUBY_ASSERT(ISEQ_BODY(iseq)->param.flags.forwardable);
+
// Setting up local size and param size
- if (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);
- }
+ local_size = local_size + vm_ci_argc(calling->cd->ci);
+ param_size = param_size + vm_ci_argc(calling->cd->ci);
const int opt_pc = vm_callee_setup_arg(ec, calling, iseq, cfp->sp - calling->argc, param_size, local_size);
return vm_call_iseq_setup_2(ec, cfp, calling, opt_pc, param_size, local_size);
@@ -4690,8 +4706,14 @@ vm_call_method_each_type(rb_execution_context_t *ec, rb_control_frame_t *cfp, st
switch (cme->def->type) {
case VM_METHOD_TYPE_ISEQ:
- CC_SET_FASTPATH(cc, vm_call_iseq_setup, TRUE);
- return vm_call_iseq_setup(ec, cfp, calling);
+ if (ISEQ_BODY(def_iseq_ptr(cme->def))->param.flags.forwardable) {
+ CC_SET_FASTPATH(cc, vm_call_iseq_fwd_setup, TRUE);
+ return vm_call_iseq_fwd_setup(ec, cfp, calling);
+ }
+ else {
+ CC_SET_FASTPATH(cc, vm_call_iseq_setup, TRUE);
+ return vm_call_iseq_setup(ec, cfp, calling);
+ }
case VM_METHOD_TYPE_NOTIMPLEMENTED:
case VM_METHOD_TYPE_CFUNC: