aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--vm_args.c31
2 files changed, 28 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index d3708e0be0..cd1361e25a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jul 8 14:16:48 2016 Shugo Maeda <shugo@ruby-lang.org>
+
+ * vm_args.c (vm_caller_setup_arg_block): call rb_sym_to_proc()
+ directly to reduce method dispatch overhead.
+
Fri Jul 8 08:43:31 2016 Shugo Maeda <shugo@ruby-lang.org>
* io.c (rb_io_s_read): add description of pipes to the documentation
diff --git a/vm_args.c b/vm_args.c
index 4917b7f360..06760f5c64 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -766,12 +766,23 @@ vm_caller_setup_arg_kw(rb_control_frame_t *cfp, struct rb_calling_info *calling,
calling->argc -= kw_len - 1;
}
+static inline void
+vm_caller_setup_proc_as_block(rb_control_frame_t *reg_cfp,
+ struct rb_calling_info *calling,
+ VALUE proc)
+{
+ rb_proc_t *po;
+
+ GetProcPtr(proc, po);
+ calling->blockptr = &po->block;
+ RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp)->proc = proc;
+}
+
static void
vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super)
{
if (ci->flag & VM_CALL_ARGS_BLOCKARG) {
- rb_proc_t *po;
VALUE proc;
proc = *(--reg_cfp->sp);
@@ -779,11 +790,17 @@ vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
if (NIL_P(proc)) {
calling->blockptr = NULL;
}
- else if (LIKELY(!(ci->flag & VM_CALL_TAILCALL)) && SYMBOL_P(proc) &&
+ else if (SYMBOL_P(proc) &&
rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) {
- calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp);
- calling->blockptr->iseq = (rb_iseq_t *)proc;
- calling->blockptr->proc = proc;
+ if (LIKELY(!(ci->flag & VM_CALL_TAILCALL))) {
+ calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp);
+ calling->blockptr->iseq = (rb_iseq_t *)proc;
+ calling->blockptr->proc = proc;
+ }
+ else {
+ proc = rb_sym_to_proc(proc);
+ vm_caller_setup_proc_as_block(reg_cfp, calling, proc);
+ }
}
else {
if (!rb_obj_is_proc(proc)) {
@@ -797,9 +814,7 @@ vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
}
proc = b;
}
- GetProcPtr(proc, po);
- calling->blockptr = &po->block;
- RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp)->proc = proc;
+ vm_caller_setup_proc_as_block(reg_cfp, calling, proc);
}
}
else if (blockiseq != 0) { /* likely */