ruby-changes:40023
From: ko1 <ko1@a...>
Date: Sun, 11 Oct 2015 05:32:20 +0900 (JST)
Subject: [ruby-changes:40023] ko1:r52104 (trunk): * vm.c (invoke_block_from_c): split this function into several
ko1 2015-10-11 05:32:07 +0900 (Sun, 11 Oct 2015) New Revision: 52104 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52104 Log: * vm.c (invoke_block_from_c): split this function into several functions. * vm_insnhelper.c (vm_yield_callee_setup_arg): remove this function beacuse it is only delegation function. Modified files: trunk/ChangeLog trunk/vm.c trunk/vm_eval.c trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 52103) +++ ChangeLog (revision 52104) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Oct 11 05:29:51 2015 Koichi Sasada <ko1@a...> + + * vm.c (invoke_block_from_c): split this function into several + functions. + + * vm_insnhelper.c (vm_yield_callee_setup_arg): remove this function + beacuse it is only delegation function. + Sun Oct 11 03:48:46 2015 Koichi Sasada <ko1@a...> * gc.c (newobj_of_slowpass): fix typo (pass -> path). Index: vm_eval.c =================================================================== --- vm_eval.c (revision 52103) +++ vm_eval.c (revision 52104) @@ -1054,7 +1054,7 @@ rb_yield_splat(VALUE values) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1054 VALUE rb_yield_block(VALUE val, VALUE arg, int argc, const VALUE *argv, VALUE blockarg) { - const rb_block_t *blockptr = 0; + const rb_block_t *blockptr = NULL; if (!NIL_P(blockarg)) { rb_proc_t *blockproc; GetProcPtr(blockarg, blockproc); Index: vm.c =================================================================== --- vm.c (revision 52103) +++ vm.c (revision 52104) @@ -803,98 +803,127 @@ rb_binding_add_dynavars(rb_binding_t *bi https://github.com/ruby/ruby/blob/trunk/vm.c#L803 /* C -> Ruby: block */ static inline VALUE -invoke_block_from_c(rb_thread_t *th, const rb_block_t *block, - VALUE self, int argc, const VALUE *argv, - const rb_block_t *blockptr, const rb_cref_t *cref, - int splattable) +invoke_block(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const rb_block_t *block, const rb_cref_t *cref, int type, int opt_pc) { - if (SPECIAL_CONST_P(block->iseq)) { + int arg_size = iseq->body->param.size; + + vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH, self, + VM_ENVVAL_PREV_EP_PTR(block->ep), + (VALUE)cref, /* cref or method */ + iseq->body->iseq_encoded + opt_pc, + th->cfp->sp + arg_size, iseq->body->local_size - arg_size, + iseq->body->stack_max); + + return vm_exec(th); +} + +static VALUE +invoke_bmethod(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const rb_block_t *block, int type, int opt_pc) +{ + /* bmethod */ + int arg_size = iseq->body->param.size; + const rb_callable_method_entry_t *me = th->passed_bmethod_me; + VALUE ret; + + th->passed_bmethod_me = NULL; + + vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self, + VM_ENVVAL_PREV_EP_PTR(block->ep), + (VALUE)me, /* cref or method (TODO: can we ignore cref?) */ + iseq->body->iseq_encoded + opt_pc, + th->cfp->sp + arg_size, iseq->body->local_size - arg_size, + iseq->body->stack_max); + + RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->called_id); + EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->called_id, me->owner, Qnil); + ret = vm_exec(th); + EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, self, me->called_id, me->owner, ret); + RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->owner, me->called_id); + return ret; +} + +static inline VALUE +invoke_block_from_c_0(rb_thread_t *th, const rb_block_t *block, + VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr, + const rb_cref_t *cref, const int splattable) +{ + if (UNLIKELY(SPECIAL_CONST_P(block->iseq))) { return Qnil; } - else if (!RUBY_VM_IFUNC_P(block->iseq)) { - VALUE ret; + else if (LIKELY(RUBY_VM_NORMAL_ISEQ_P(block->iseq))) { const rb_iseq_t *iseq = block->iseq; - const rb_control_frame_t *cfp; - int i, opt_pc, arg_size = iseq->body->param.size; + int i, opt_pc; int type = block_proc_is_lambda(block->proc) ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK; - const rb_callable_method_entry_t *me = th->passed_bmethod_me; - th->passed_bmethod_me = NULL; - cfp = th->cfp; + VALUE *sp = th->cfp->sp; for (i=0; i<argc; i++) { - cfp->sp[i] = argv[i]; + sp[i] = argv[i]; } - opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr, + opt_pc = vm_yield_setup_args(th, iseq, argc, sp, blockptr, (type == VM_FRAME_MAGIC_LAMBDA ? (splattable ? arg_setup_lambda : arg_setup_method) : arg_setup_block)); - if (me != 0) { - /* bmethod */ - vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self, - VM_ENVVAL_PREV_EP_PTR(block->ep), - (VALUE)me, /* cref or method (TODO: can we ignore cref?) */ - iseq->body->iseq_encoded + opt_pc, - cfp->sp + arg_size, iseq->body->local_size - arg_size, - iseq->body->stack_max); - - RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->called_id); - EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->called_id, me->owner, Qnil); + if (th->passed_bmethod_me == NULL) { + return invoke_block(th, iseq, self, block, cref, type, opt_pc); } else { - vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH, self, - VM_ENVVAL_PREV_EP_PTR(block->ep), - (VALUE)cref, /* cref or method */ - iseq->body->iseq_encoded + opt_pc, - cfp->sp + arg_size, iseq->body->local_size - arg_size, - iseq->body->stack_max); + return invoke_bmethod(th, iseq, self, block, type, opt_pc); } - ret = vm_exec(th); - - if (me) { - /* bmethod */ - EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, self, me->called_id, me->owner, ret); - RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->owner, me->called_id); - } - - return ret; } else { return vm_yield_with_cfunc(th, block, self, argc, argv, blockptr); } } +static VALUE +invoke_block_from_c_splattable(rb_thread_t *th, const rb_block_t *block, + VALUE self, int argc, const VALUE *argv, + const rb_block_t *blockptr, const rb_cref_t *cref) +{ + return invoke_block_from_c_0(th, block, self, argc, argv, blockptr, cref, TRUE); +} + +static VALUE +invoke_block_from_c_unsplattable(rb_thread_t *th, const rb_block_t *block, + VALUE self, int argc, const VALUE *argv, + const rb_block_t *blockptr, const rb_cref_t *cref) +{ + return invoke_block_from_c_0(th, block, self, argc, argv, blockptr, cref, FALSE); +} + + static inline const rb_block_t * check_block(rb_thread_t *th) { const rb_block_t *blockptr = VM_CF_BLOCK_PTR(th->cfp); - if (blockptr == 0) { + if (UNLIKELY(blockptr == 0)) { rb_vm_localjump_error("no block given", Qnil, 0); } return blockptr; } -static inline VALUE +static VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const rb_cref_t *cref) { const rb_block_t *blockptr = check_block(th); - return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref, 1); + return invoke_block_from_c_splattable(th, blockptr, blockptr->self, argc, argv, NULL, cref); } -static inline VALUE +static VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv) { const rb_block_t *blockptr = check_block(th); - return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0, 1); + return invoke_block_from_c_splattable(th, blockptr, blockptr->self, argc, argv, NULL, NULL); } -static inline VALUE +static VALUE vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, const rb_block_t *blockargptr) { const rb_block_t *blockptr = check_block(th); - return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, blockargptr, 0, 1); + return invoke_block_from_c_splattable(th, blockptr, blockptr->self, argc, argv, blockargptr, NULL); } static VALUE @@ -908,7 +937,7 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_ https://github.com/ruby/ruby/blob/trunk/vm.c#L937 TH_PUSH_TAG(th); if ((state = EXEC_TAG()) == 0) { th->safe_level = proc->safe_level; - val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0, 0); + val = invoke_block_from_c_unsplattable(th, &proc->block, self, argc, argv, blockptr, NULL); } TH_POP_TAG(); @@ -924,7 +953,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L953 vm_invoke_bmethod(rb_thread_t *th, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr) { - return invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0, 0); + return invoke_block_from_c_unsplattable(th, &proc->block, self, argc, argv, blockptr, NULL); } VALUE Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 52103) +++ vm_insnhelper.c (revision 52104) @@ -2275,7 +2275,7 @@ block_proc_is_lambda(const VALUE procval https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2275 } } -static inline VALUE +static VALUE vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, VALUE self, int argc, const VALUE *argv, const rb_block_t *blockargptr) @@ -2318,14 +2318,6 @@ vm_yield_with_cfunc(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2318 } static int -vm_yield_callee_setup_arg(rb_thread_t *th, struct rb_calling_info *calling, - const struct rb_call_info *ci, const rb_iseq_t *iseq, - VALUE *argv, enum arg_setup_type arg_setup_type) -{ - return vm_callee_setup_block_arg(th, calling, ci, iseq, argv, arg_setup_type); -} - -static int vm_yield_setup_args(rb_thread_t *th, const rb_iseq_t *iseq, const int argc, VALUE *argv, const rb_block_t *blockptr, enum arg_setup_type arg_setup_type) { struct rb_calling_info calling_entry, *calling; @@ -2338,10 +2330,11 @@ vm_yield_setup_args(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2330 ci_entry.flag = 0; ci = &ci_entry; - return vm_yield_callee_setup_arg(th, calling, ci, iseq, argv, arg_setup_type); + return vm_callee_setup_block_arg(th, calling, ci, iseq, argv, arg_setup_type); } /* ruby iseq -> ruby block iseq */ + static VALUE vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_call_info *ci) { @@ -2354,11 +2347,11 @@ vm_invoke_block(rb_thread_t *th, rb_cont https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2347 } iseq = block->iseq; - if (!RUBY_VM_IFUNC_P(iseq)) { + if (RUBY_VM_NORMAL_ISEQ_P(iseq)) { const int arg_size = iseq->body->param.size; int is_lambda = block_proc_is_lambda(block->proc); VALUE * const rsp = GET_SP() - calling->argc; - int opt_pc = vm_yield_callee_setup_arg(th, calling, ci, iseq, rsp, is_lambda ? arg_setup_lambda : arg_setup_block); + int opt_pc = vm_callee_setup_block_arg(th, calling, ci, iseq, rsp, is_lambda ? arg_setup_lambda : arg_setup_block); SET_SP(rsp); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/