mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm_insnhelper.c: move vm_callee_setup_block_arg() (and related
functions) to the latter location. This moving recovers performance a little. [Bug #11829] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9da8a29760
commit
11f4334f75
2 changed files with 89 additions and 82 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Tue Dec 22 20:14:47 2015 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Tue Dec 22 15:21:11 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* string.c (str_compat_and_valid): as scrub does nothing for dummy
|
* string.c (str_compat_and_valid): as scrub does nothing for dummy
|
||||||
|
|
164
vm_insnhelper.c
164
vm_insnhelper.c
|
@ -1312,88 +1312,6 @@ static rb_method_definition_t *method_definition_create(rb_method_type_t type, I
|
||||||
static void method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts);
|
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 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 *
|
static const rb_iseq_t *
|
||||||
def_iseq_ptr(rb_method_definition_t *def)
|
def_iseq_ptr(rb_method_definition_t *def)
|
||||||
{
|
{
|
||||||
|
@ -1418,6 +1336,17 @@ vm_call_iseq_setup_normal_0start(rb_thread_t *th, rb_control_frame_t *cfp, struc
|
||||||
return vm_call_iseq_setup_normal(th, cfp, calling, ci, cc, 0, param, local);
|
return vm_call_iseq_setup_normal(th, cfp, calling, ci, cc, 0, param, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
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,
|
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)
|
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, const rb_block_t *block, VALUE self,
|
||||||
return val;
|
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
|
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)
|
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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue