1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

encourage inlining for vm_sendish()

Some tunings.
* add `inline` for vm_sendish()
* pass enum instead of func ptr to vm_sendish()
* reorder initial order of `calling` struct.
* add ALWAYS_INLINE for vm_search_method_fastpath()
* call vm_search_method_fastpath() from vm_sendish()
This commit is contained in:
Koichi Sasada 2020-12-17 15:46:36 +09:00
parent 5d74894f2b
commit 9213771817
Notes: git 2020-12-17 16:54:08 +09:00
2 changed files with 32 additions and 38 deletions

View file

@ -767,7 +767,7 @@ send
// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{ {
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false); VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false);
val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_method_wrap); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
if (val == Qundef) { if (val == Qundef) {
RESTORE_REGS(); RESTORE_REGS();
@ -786,7 +786,7 @@ opt_send_without_block
// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{ {
VALUE bh = VM_BLOCK_HANDLER_NONE; VALUE bh = VM_BLOCK_HANDLER_NONE;
val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_method_wrap); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
if (val == Qundef) { if (val == Qundef) {
RESTORE_REGS(); RESTORE_REGS();
@ -873,7 +873,7 @@ invokesuper
// attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci); // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
{ {
VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true); VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true);
val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_super_method); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super);
if (val == Qundef) { if (val == Qundef) {
RESTORE_REGS(); RESTORE_REGS();
@ -892,7 +892,7 @@ invokeblock
// attr rb_snum_t comptime_sp_inc = sp_inc_of_invokeblock(ci); // attr rb_snum_t comptime_sp_inc = sp_inc_of_invokeblock(ci);
{ {
VALUE bh = VM_BLOCK_HANDLER_NONE; VALUE bh = VM_BLOCK_HANDLER_NONE;
val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_invokeblock); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock);
if (val == Qundef) { if (val == Qundef) {
RESTORE_REGS(); RESTORE_REGS();

View file

@ -1795,7 +1795,9 @@ vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
return cc; return cc;
} }
static const struct rb_callcache * ALWAYS_INLINE(static const struct rb_callcache *vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass));
static inline const struct rb_callcache *
vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass) vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
{ {
const struct rb_callcache *cc = cd->cc; const struct rb_callcache *cc = cd->cc;
@ -4409,14 +4411,6 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv
} }
} }
static const struct rb_callcache *
vm_search_method_wrap(const struct rb_control_frame_struct *reg_cfp,
struct rb_call_data *cd,
VALUE recv)
{
return vm_search_method((VALUE)reg_cfp->iseq, cd, recv);
}
static VALUE static VALUE
vm_invokeblock_i(struct rb_execution_context_struct *ec, vm_invokeblock_i(struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *reg_cfp, struct rb_control_frame_struct *reg_cfp,
@ -4433,47 +4427,47 @@ vm_invokeblock_i(struct rb_execution_context_struct *ec,
} }
} }
static const struct rb_callcache * enum method_explorer_type {
vm_search_invokeblock(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv) mexp_search_method,
{ mexp_search_invokeblock,
static const struct rb_callcache cc = { mexp_search_super,
.flags = T_IMEMO | (imemo_callcache << FL_USHIFT) | VM_CALLCACHE_UNMARKABLE, };
.klass = 0,
.cme_ = 0,
.call_ = vm_invokeblock_i,
.aux_ = {0},
};
return &cc; static inline VALUE
}
static VALUE
vm_sendish( vm_sendish(
struct rb_execution_context_struct *ec, struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *reg_cfp, struct rb_control_frame_struct *reg_cfp,
struct rb_call_data *cd, struct rb_call_data *cd,
VALUE block_handler, VALUE block_handler,
const struct rb_callcache *(*method_explorer)( enum method_explorer_type method_explorer)
const struct rb_control_frame_struct *cfp,
struct rb_call_data *cd,
VALUE recv))
{ {
VALUE val; VALUE val;
int argc = vm_ci_argc(cd->ci); const struct rb_callinfo *ci = cd->ci;
const struct rb_callcache *cc;
int argc = vm_ci_argc(ci);
VALUE recv = TOPN(argc); VALUE recv = TOPN(argc);
const struct rb_callcache *cc = method_explorer(GET_CFP(), cd, recv);
const struct rb_callinfo *ci = cd->ci; // TODO: vm_search_super_method can update ci!!
struct rb_calling_info calling = { struct rb_calling_info calling = {
.ci = cd->ci,
.cc = cc,
.block_handler = block_handler, .block_handler = block_handler,
.kw_splat = IS_ARGS_KW_SPLAT(ci) > 0, .kw_splat = IS_ARGS_KW_SPLAT(ci) > 0,
.recv = recv, .recv = recv,
.argc = argc, .argc = argc,
.ci = ci,
}; };
val = vm_cc_call(cc)(ec, GET_CFP(), &calling); switch (method_explorer) {
case mexp_search_method:
calling.cc = cc = vm_search_method_fastpath((VALUE)reg_cfp->iseq, cd, CLASS_OF(recv));
val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
break;
case mexp_search_super:
calling.cc = cc = vm_search_super_method(reg_cfp, cd, recv);
calling.ci = cd->ci; // TODO: does it safe?
val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
break;
case mexp_search_invokeblock:
val = vm_invokeblock_i(ec, GET_CFP(), &calling);
break;
}
if (val != Qundef) { if (val != Qundef) {
return val; /* CFUNC normal return */ return val; /* CFUNC normal return */