ruby-changes:41163
From: ko1 <ko1@a...>
Date: Tue, 22 Dec 2015 20:20:34 +0900 (JST)
Subject: [ruby-changes:41163] ko1:r53236 (trunk): * vm_insnhelper.c: move vm_callee_setup_block_arg() (and related
ko1 2015-12-22 20:20:12 +0900 (Tue, 22 Dec 2015) New Revision: 53236 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53236 Log: * vm_insnhelper.c: move vm_callee_setup_block_arg() (and related functions) to the latter location. This moving recovers performance a little. [Bug #11829] Modified files: trunk/ChangeLog trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 53235) +++ ChangeLog (revision 53236) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Dec 22 20:14:47 2015 Koichi Sasada <ko1@a...> + + * vm_insnhelper.c: move vm_callee_setup_block_arg() (and related + functions) to the latter location. + This moving recovers performance a little. + [Bug #11829] + Tue Dec 22 15:21:11 2015 Nobuyoshi Nakada <nobu@r...> * string.c (str_compat_and_valid): as scrub does nothing for dummy Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 53235) +++ vm_insnhelper.c (revision 53236) @@ -1312,88 +1312,6 @@ static rb_method_definition_t *method_de https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1312 static void method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts); static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2); -static inline VALUE -vm_callee_setup_block_arg_arg0_check(VALUE *argv) -{ - VALUE ary, arg0 = argv[0]; - ary = rb_check_array_type(arg0); - argv[0] = arg0; - return ary; -} - -static inline int -vm_callee_setup_block_arg_arg0_splat(rb_control_frame_t *cfp, const rb_iseq_t *iseq, VALUE *argv, VALUE ary) -{ - int i; - long len = RARRAY_LEN(ary); - - CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num); - - for (i=0; i<len && i<iseq->body->param.lead_num; i++) { - argv[i] = RARRAY_AREF(ary, i); - } - - return i; -} - -static inline int -simple_iseq_p(const rb_iseq_t *iseq) -{ - return iseq->body->param.flags.has_opt == FALSE && - iseq->body->param.flags.has_rest == FALSE && - iseq->body->param.flags.has_post == FALSE && - iseq->body->param.flags.has_kw == FALSE && - iseq->body->param.flags.has_kwrest == FALSE && - iseq->body->param.flags.has_block == FALSE; -} - -static inline int -vm_callee_setup_block_arg(rb_thread_t *th, struct rb_calling_info *calling, const struct rb_call_info *ci, const rb_iseq_t *iseq, VALUE *argv, const enum arg_setup_type arg_setup_type) -{ - if (LIKELY(simple_iseq_p(iseq))) { - rb_control_frame_t *cfp = th->cfp; - VALUE arg0; - - CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */ - - if (arg_setup_type == arg_setup_block && - calling->argc == 1 && - iseq->body->param.flags.has_lead && - !iseq->body->param.flags.ambiguous_param0 && - !NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) { - calling->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0); - } - - if (calling->argc != iseq->body->param.lead_num) { - if (arg_setup_type == arg_setup_block) { - if (calling->argc < iseq->body->param.lead_num) { - int i; - CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num); - for (i=calling->argc; i<iseq->body->param.lead_num; i++) argv[i] = Qnil; - calling->argc = iseq->body->param.lead_num; /* fill rest parameters */ - } - else if (calling->argc > iseq->body->param.lead_num) { - calling->argc = iseq->body->param.lead_num; /* simply truncate arguments */ - } - } - else if (arg_setup_type == arg_setup_lambda && - calling->argc == 1 && - !NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv)) && - RARRAY_LEN(arg0) == iseq->body->param.lead_num) { - calling->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0); - } - else { - argument_arity_error(th, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num); - } - } - - return 0; - } - else { - return setup_parameters_complex(th, iseq, calling, ci, argv, arg_setup_type); - } -} - static const rb_iseq_t * def_iseq_ptr(rb_method_definition_t *def) { @@ -1419,6 +1337,17 @@ vm_call_iseq_setup_normal_0start(rb_thre https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1337 } static inline int +simple_iseq_p(const rb_iseq_t *iseq) +{ + return iseq->body->param.flags.has_opt == FALSE && + iseq->body->param.flags.has_rest == FALSE && + iseq->body->param.flags.has_post == FALSE && + iseq->body->param.flags.has_kw == FALSE && + iseq->body->param.flags.has_kwrest == FALSE && + iseq->body->param.flags.has_block == FALSE; +} + +static inline int vm_callee_setup_arg(rb_thread_t *th, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const rb_iseq_t *iseq, VALUE *argv, int param_size, int local_size) { @@ -2408,6 +2337,77 @@ vm_yield_with_cfunc(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2337 return val; } +static inline int +vm_callee_setup_block_arg_arg0_splat(rb_control_frame_t *cfp, const rb_iseq_t *iseq, VALUE *argv, VALUE ary) +{ + int i; + long len = RARRAY_LEN(ary); + + CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num); + + for (i=0; i<len && i<iseq->body->param.lead_num; i++) { + argv[i] = RARRAY_AREF(ary, i); + } + + return i; +} + +static inline VALUE +vm_callee_setup_block_arg_arg0_check(VALUE *argv) +{ + VALUE ary, arg0 = argv[0]; + ary = rb_check_array_type(arg0); + argv[0] = arg0; + return ary; +} + +static int +vm_callee_setup_block_arg(rb_thread_t *th, struct rb_calling_info *calling, const struct rb_call_info *ci, const rb_iseq_t *iseq, VALUE *argv, const enum arg_setup_type arg_setup_type) +{ + if (simple_iseq_p(iseq)) { + rb_control_frame_t *cfp = th->cfp; + VALUE arg0; + + CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */ + + if (arg_setup_type == arg_setup_block && + calling->argc == 1 && + iseq->body->param.flags.has_lead && + !iseq->body->param.flags.ambiguous_param0 && + !NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) { + calling->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0); + } + + if (calling->argc != iseq->body->param.lead_num) { + if (arg_setup_type == arg_setup_block) { + if (calling->argc < iseq->body->param.lead_num) { + int i; + CHECK_VM_STACK_OVERFLOW(cfp, iseq->body->param.lead_num); + for (i=calling->argc; i<iseq->body->param.lead_num; i++) argv[i] = Qnil; + calling->argc = iseq->body->param.lead_num; /* fill rest parameters */ + } + else if (calling->argc > iseq->body->param.lead_num) { + calling->argc = iseq->body->param.lead_num; /* simply truncate arguments */ + } + } + else if (arg_setup_type == arg_setup_lambda && + calling->argc == 1 && + !NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv)) && + RARRAY_LEN(arg0) == iseq->body->param.lead_num) { + calling->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0); + } + else { + argument_arity_error(th, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num); + } + } + + return 0; + } + else { + return setup_parameters_complex(th, iseq, calling, ci, 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) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/