Skip to content

Commit dc970fc

Browse files
committed
Set a fast path for forwardable iseqs
1 parent bff1026 commit dc970fc

2 files changed

Lines changed: 34 additions & 7 deletions

File tree

vm_eval.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,12 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
215215
*reg_cfp->sp++ = argv[i];
216216
}
217217

218-
vm_call_iseq_setup(ec, reg_cfp, calling);
218+
if (ISEQ_BODY(def_iseq_ptr(vm_cc_cme(cc)->def))->param.flags.forwardable) {
219+
vm_call_iseq_fwd_setup(ec, reg_cfp, calling);
220+
}
221+
else {
222+
vm_call_iseq_setup(ec, reg_cfp, calling);
223+
}
219224
VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);
220225
return vm_exec(ec); // CHECK_INTS in this function
221226
}

vm_insnhelper.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3306,11 +3306,27 @@ vm_call_iseq_setup(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct r
33063306
int param_size = ISEQ_BODY(iseq)->param.size;
33073307
int local_size = ISEQ_BODY(iseq)->local_table_size;
33083308

3309+
RUBY_ASSERT(!ISEQ_BODY(iseq)->param.flags.forwardable);
3310+
3311+
const int opt_pc = vm_callee_setup_arg(ec, calling, iseq, cfp->sp - calling->argc, param_size, local_size);
3312+
return vm_call_iseq_setup_2(ec, cfp, calling, opt_pc, param_size, local_size);
3313+
}
3314+
3315+
static VALUE
3316+
vm_call_iseq_fwd_setup(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
3317+
{
3318+
RB_DEBUG_COUNTER_INC(ccf_iseq_setup);
3319+
3320+
const struct rb_callcache *cc = calling->cc;
3321+
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
3322+
int param_size = ISEQ_BODY(iseq)->param.size;
3323+
int local_size = ISEQ_BODY(iseq)->local_table_size;
3324+
3325+
RUBY_ASSERT(ISEQ_BODY(iseq)->param.flags.forwardable);
3326+
33093327
// Setting up local size and param size
3310-
if (ISEQ_BODY(iseq)->param.flags.forwardable) {
3311-
local_size = local_size + vm_ci_argc(calling->cd->ci);
3312-
param_size = param_size + vm_ci_argc(calling->cd->ci);
3313-
}
3328+
local_size = local_size + vm_ci_argc(calling->cd->ci);
3329+
param_size = param_size + vm_ci_argc(calling->cd->ci);
33143330

33153331
const int opt_pc = vm_callee_setup_arg(ec, calling, iseq, cfp->sp - calling->argc, param_size, local_size);
33163332
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
46904706

46914707
switch (cme->def->type) {
46924708
case VM_METHOD_TYPE_ISEQ:
4693-
CC_SET_FASTPATH(cc, vm_call_iseq_setup, TRUE);
4694-
return vm_call_iseq_setup(ec, cfp, calling);
4709+
if (ISEQ_BODY(def_iseq_ptr(cme->def))->param.flags.forwardable) {
4710+
CC_SET_FASTPATH(cc, vm_call_iseq_fwd_setup, TRUE);
4711+
return vm_call_iseq_fwd_setup(ec, cfp, calling);
4712+
}
4713+
else {
4714+
CC_SET_FASTPATH(cc, vm_call_iseq_setup, TRUE);
4715+
return vm_call_iseq_setup(ec, cfp, calling);
4716+
}
46954717

46964718
case VM_METHOD_TYPE_NOTIMPLEMENTED:
46974719
case VM_METHOD_TYPE_CFUNC:

0 commit comments

Comments
 (0)