summaryrefslogtreecommitdiff
path: root/insns.def
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-14 16:59:05 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-14 16:59:05 +0000
commitcbd597e9bc05eac7249e91dcdb4f1c1c75a53cf5 (patch)
tree8f570f2e813466ef8fa0ac3f564a638b69164773 /insns.def
parente8c234577fa7061a22f0dc515aefdc8dbc61f3b5 (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 'insns.def')
-rw-r--r--insns.def140
1 files changed, 51 insertions, 89 deletions
diff --git a/insns.def b/insns.def
index ae1998af63..6e516fbd8d 100644
--- a/insns.def
+++ b/insns.def
@@ -952,100 +952,62 @@ defineclass
/**
@c method/iterator
- @e obj.send(id, args..) # args.size => num
- @j メソッド呼び出しを行う。
- obj.send(id, args..) # args.size => num
- flag & VM_CALL_ARGS_SPLAT_BIT != 0 -> splat last arg
- flag & VM_CALL_ARGS_BLOCKARG_BIT != 0 -> Proc as Block
- flag & VM_CALL_FCALL_BIT != 0 -> FCALL ( func() )
- flag & VM_CALL_VCALL_BIT != 0 -> VCALL ( func )
- ...
+ @e invoke method.
+ @j メソッド呼び出しを行う。ci に必要な情報が格納されている。
*/
DEFINE_INSN
send
-(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, CALL_INFO ci)
+(CALL_INFO ci)
(...)
-(VALUE val) // inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
+(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
{
- const rb_method_entry_t *me;
- VALUE recv, klass, defined_class;
- rb_block_t *blockptr = 0;
- VALUE flag = op_flag;
- int num = caller_setup_args(th, GET_CFP(), flag, (int)op_argc,
- (rb_iseq_t *)blockiseq, &blockptr);
- ID id = op_id;
+ ci->argc = ci->orig_argc;
+ ci->blockptr = 0;
- /* get receiver */
- recv = TOPN(num);
- klass = CLASS_OF(recv);
- me = vm_method_search(id, klass, ci, &defined_class);
- CALL_METHOD(num, blockptr, flag, id, me, recv, defined_class);
+ if (!LIKELY(ci->flag & VM_CALL_ARGS_SKIP_SETUP)) {
+ vm_caller_setup_args(th, reg_cfp, ci);
+ }
+ vm_search_method(ci, ci->recv = TOPN(ci->argc));
+ CALL_METHOD(ci);
}
/**
@c method/iterator
@e super(args) # args.size => num
- @j super を実行する。
- super(args) # args.size => num
- flag 等オペランドの意味は send と同じ。
+ @j super を実行する。ci に必要な情報が格納されている。
*/
DEFINE_INSN
invokesuper
-(rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag)
+(CALL_INFO ci)
(...)
-(VALUE val) // inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
+(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
{
- rb_block_t *blockptr = !(op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? GET_BLOCK_PTR() : 0;
- VALUE flag = op_flag;
- int num = caller_setup_args(th, GET_CFP(), flag,
- (int)op_argc, blockiseq, &blockptr);
- VALUE recv, klass;
- ID id;
- const rb_method_entry_t *me;
- rb_iseq_t *ip;
-
- flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
-
- klass = GET_CFP()->klass;
- if (NIL_P(klass)) {
- vm_super_outside();
- }
- if (!NIL_P(RCLASS_REFINED_CLASS(klass))) {
- klass = RCLASS_REFINED_CLASS(klass);
- }
- recv = GET_SELF();
- if (!rb_obj_is_kind_of(recv, klass)) {
- rb_raise(rb_eNotImpError, "super from singleton method that is defined to multiple classes is not supported; this will be fixed in 2.0.0 or later");
- }
- vm_search_superclass(GET_CFP(), GET_ISEQ(), TOPN(num), &id, &klass);
+ ci->argc = ci->orig_argc;
+ ci->blockptr = !(ci->flag & VM_CALL_ARGS_BLOCKARG_BIT) ? GET_BLOCK_PTR() : 0;
- ip = GET_ISEQ();
- while (ip && !ip->klass) {
- ip = ip->parent_iseq;
- }
- me = rb_method_entry(klass, id, &klass);
- if (me && me->def->type == VM_METHOD_TYPE_ISEQ &&
- me->def->body.iseq == ip) {
- klass = RCLASS_SUPER(klass);
- me = rb_method_entry_get_with_refinements(Qnil, klass, id, &klass);
+ if (!LIKELY(ci->flag & VM_CALL_ARGS_SKIP_SETUP)) {
+ vm_caller_setup_args(th, reg_cfp, ci);
}
-
- CALL_METHOD(num, blockptr, flag, id, me, recv, klass);
+ ci->recv = GET_SELF();
+ vm_search_super_method(th, GET_CFP(), ci);
+ CALL_METHOD(ci);
}
/**
@c method/iterator
- @e yield(args) # args.size => num, flag shows expand argument or not
+ @e yield(args)
@j yield を実行する。
- yield(args) # args.size => num
*/
DEFINE_INSN
invokeblock
-(rb_num_t num, rb_num_t flag)
+(CALL_INFO ci)
(...)
-(VALUE val) // inc += 1 - num;
+(VALUE val) // inc += 1 - ci->orig_argc;
{
- val = vm_invoke_block(th, GET_CFP(), num, flag);
+ ci->argc = ci->orig_argc;
+ ci->blockptr = 0;
+ ci->recv = GET_SELF();
+ val = vm_invoke_block(th, GET_CFP(), ci);
if (val == Qundef) {
RESTORE_REGS();
NEXT_INSN();
@@ -1338,7 +1300,7 @@ opt_plus
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idPLUS, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1386,7 +1348,7 @@ opt_minus
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idMINUS, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1439,7 +1401,7 @@ opt_mult
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idMULT, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1502,7 +1464,7 @@ opt_div
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idDIV, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1566,7 +1528,7 @@ opt_mod
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idMOD, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1587,7 +1549,7 @@ opt_eq
/* other */
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idEq, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1603,10 +1565,10 @@ opt_neq
(VALUE val)
{
extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
- const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ci, 0);
+ vm_search_method(ci, recv);
val = Qundef;
- if (check_cfunc(me, rb_obj_not_equal)) {
+ if (check_cfunc(ci->me, rb_obj_not_equal)) {
val = opt_eq_func(recv, obj, ci_eq);
if (val != Qundef) {
@@ -1618,7 +1580,7 @@ opt_neq
/* other */
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idNeq, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1662,7 +1624,7 @@ opt_lt
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idLT, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1697,7 +1659,7 @@ opt_le
/* other */
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idLE, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1741,7 +1703,7 @@ opt_gt
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idGT, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1775,7 +1737,7 @@ opt_ge
else {
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idGE, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1807,7 +1769,7 @@ opt_ltlt
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idLTLT, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1837,7 +1799,7 @@ opt_aref
INSN_LABEL(normal_dispatch):
PUSH(recv);
PUSH(obj);
- CALL_SIMPLE_METHOD(1, idAREF, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1870,7 +1832,7 @@ opt_aset
PUSH(recv);
PUSH(obj);
PUSH(set);
- CALL_SIMPLE_METHOD(2, idASET, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1905,7 +1867,7 @@ opt_length
else {
INSN_LABEL(normal_dispatch):
PUSH(recv);
- CALL_SIMPLE_METHOD(0, idLength, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1940,7 +1902,7 @@ opt_size
else {
INSN_LABEL(normal_dispatch):
PUSH(recv);
- CALL_SIMPLE_METHOD(0, idSize, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -1978,7 +1940,7 @@ opt_empty_p
else {
INSN_LABEL(normal_dispatch):
PUSH(recv);
- CALL_SIMPLE_METHOD(0, idEmptyP, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -2025,7 +1987,7 @@ opt_succ
if (0) {
INSN_LABEL(normal_dispatch):
PUSH(recv);
- CALL_SIMPLE_METHOD(0, idSucc, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}
@@ -2041,14 +2003,14 @@ opt_not
(VALUE val)
{
extern VALUE rb_obj_not(VALUE obj);
- const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ci, 0);
+ vm_search_method(ci, recv);
- if (check_cfunc(me, rb_obj_not)) {
+ if (check_cfunc(ci->me, rb_obj_not)) {
val = RTEST(recv) ? Qfalse : Qtrue;
}
else {
PUSH(recv);
- CALL_SIMPLE_METHOD(0, idNot, recv);
+ CALL_SIMPLE_METHOD(recv);
}
}