diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-10-14 16:59:05 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-10-14 16:59:05 +0000 |
commit | cbd597e9bc05eac7249e91dcdb4f1c1c75a53cf5 (patch) | |
tree | 8f570f2e813466ef8fa0ac3f564a638b69164773 /vm_eval.c | |
parent | e8c234577fa7061a22f0dc515aefdc8dbc61f3b5 (diff) |
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_eval.c')
-rw-r--r-- | vm_eval.c | 41 |
1 files changed, 24 insertions, 17 deletions
@@ -37,14 +37,23 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, { const rb_method_definition_t *def = me->def; VALUE val; - VALUE klass = defined_class; - const rb_block_t *blockptr = 0; + rb_call_info_t ci_entry, *ci = &ci_entry; + + ci->flag = 0; + ci->mid = id; + ci->recv = recv; + ci->defined_class = defined_class; + ci->argc = argc; + ci->me = me; if (!def) return Qnil; if (th->passed_block) { - blockptr = th->passed_block; + ci->blockptr = (rb_block_t *)th->passed_block; th->passed_block = 0; } + else { + ci->blockptr = 0; + } again: switch (def->type) { @@ -59,20 +68,19 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, *reg_cfp->sp++ = argv[i]; } - vm_setup_method(th, reg_cfp, recv, argc, blockptr, 0 /* flag */, - me, klass); + vm_setup_method(th, reg_cfp, ci); th->cfp->flag |= VM_FRAME_FLAG_FINISH; val = vm_exec(th); break; } case VM_METHOD_TYPE_NOTIMPLEMENTED: case VM_METHOD_TYPE_CFUNC: { - EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass); + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, ci->recv, ci->mid, ci->defined_class); { rb_control_frame_t *reg_cfp = th->cfp; rb_control_frame_t *cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, - recv, klass, VM_ENVVAL_BLOCK_PTR(blockptr), + ci->recv, ci->defined_class, VM_ENVVAL_BLOCK_PTR(ci->blockptr), 0, reg_cfp->sp, 1, me); cfp->me = me; @@ -83,7 +91,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, } vm_pop_frame(th); } - EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass); + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->defined_class); break; } case VM_METHOD_TYPE_ATTRSET: { @@ -97,13 +105,13 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, break; } case VM_METHOD_TYPE_BMETHOD: { - val = vm_call_bmethod(th, recv, argc, argv, blockptr, me, klass); + val = vm_call_bmethod(th, recv, argc, argv, ci->blockptr, me, ci->defined_class); break; } case VM_METHOD_TYPE_ZSUPER: { - klass = RCLASS_SUPER(klass); - if (!klass || !(me = rb_method_entry(klass, id, &klass))) { - return method_missing(recv, id, argc, argv, NOEX_SUPER); + ci->defined_class = RCLASS_SUPER(ci->defined_class); + if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, id, &ci->defined_class))) { + return method_missing(recv, ci->mid, ci->argc, argv, NOEX_SUPER); } RUBY_VM_CHECK_INTS(th); if (!(def = me->def)) return Qnil; @@ -113,10 +121,9 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, VALUE new_args = rb_ary_new4(argc, argv); RB_GC_GUARD(new_args); - rb_ary_unshift(new_args, ID2SYM(id)); - th->passed_block = blockptr; - return rb_funcall2(recv, idMethodMissing, - argc+1, RARRAY_PTR(new_args)); + rb_ary_unshift(new_args, ID2SYM(ci->mid)); + th->passed_block = ci->blockptr; + return rb_funcall2(ci->recv, idMethodMissing, argc+1, RARRAY_PTR(new_args)); } case VM_METHOD_TYPE_OPTIMIZED: { switch (def->body.optimize_type) { @@ -126,7 +133,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, case OPTIMIZED_METHOD_TYPE_CALL: { rb_proc_t *proc; GetProcPtr(recv, proc); - val = rb_vm_invoke_proc(th, proc, argc, argv, blockptr); + val = rb_vm_invoke_proc(th, proc, argc, argv, ci->blockptr); break; } default: |