diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | compile.c | 3 | ||||
-rw-r--r-- | id.c | 1 | ||||
-rw-r--r-- | id.h | 2 | ||||
-rw-r--r-- | insns.def | 37 | ||||
-rw-r--r-- | vm.c | 1 | ||||
-rw-r--r-- | vm_insnhelper.h | 1 |
7 files changed, 50 insertions, 2 deletions
@@ -1,3 +1,10 @@ +Sun Sep 6 17:31:28 2009 Koichi Sasada <ko1@atdot.net> + + * compile.c (iseq_specialized_instruction), insns.def (opt_size): + optimize #size methods (by specialized instruction). + + * id.c, id.h, vm.c, vm_insnhelper.h: ditto. + Sun Sep 6 16:13:06 2009 Koichi Sasada <ko1@atdot.net> * insns.def (setinstancevariable), vm_insnhelper.c (vm_setivar): @@ -1803,6 +1803,9 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) if (mid == idLength) { insn_set_specialized_instruction(iobj, BIN(opt_length)); } + else if (mid == idSize) { + insn_set_specialized_instruction(iobj, BIN(opt_size)); + } else if (mid == idSucc) { insn_set_specialized_instruction(iobj, BIN(opt_succ)); } @@ -34,6 +34,7 @@ Init_id(void) REGISTER_SYMID(idEach, "each"); REGISTER_SYMID(idLength, "length"); + REGISTER_SYMID(idSize, "size"); REGISTER_SYMID(idLambda, "lambda"); REGISTER_SYMID(idIntern, "intern"); REGISTER_SYMID(idGets, "gets"); @@ -98,6 +98,7 @@ enum ruby_method_ids { tIntern, tMethodMissing, tLength, + tSize, tGets, tSucc, tEach, @@ -118,6 +119,7 @@ enum ruby_method_ids { TOKEN2ID(Intern), TOKEN2ID(MethodMissing), TOKEN2ID(Length), + TOKEN2ID(Size), TOKEN2ID(Gets), TOKEN2ID(Succ), TOKEN2ID(Each), @@ -1921,8 +1921,8 @@ opt_length (VALUE recv) (VALUE val) { - if (!SPECIAL_CONST_P(recv) && - BASIC_OP_UNREDEFINED_P(BOP_LENGTH)) { + if (LIKELY(!SPECIAL_CONST_P(recv) && + BASIC_OP_UNREDEFINED_P(BOP_LENGTH))) { if (HEAP_CLASS_OF(recv) == rb_cString) { val = rb_str_length(recv); } @@ -1945,6 +1945,39 @@ opt_length /** @c optimize + @e optimized size + @j 最適化された recv.size()。 + */ +DEFINE_INSN +opt_size +() +(VALUE recv) +(VALUE val) +{ + if (LIKELY(BASIC_OP_UNREDEFINED_P(BOP_SIZE) && + !SPECIAL_CONST_P(recv))) { + if (HEAP_CLASS_OF(recv) == rb_cString) { + val = rb_str_length(recv); + } + else if (HEAP_CLASS_OF(recv) == rb_cArray) { + val = LONG2NUM(RARRAY_LEN(recv)); + } + else if (HEAP_CLASS_OF(recv) == rb_cHash) { + val = INT2FIX(RHASH_SIZE(recv)); + } + else { + goto INSN_LABEL(normal_dispatch); + } + } + else { + INSN_LABEL(normal_dispatch): + PUSH(recv); + CALL_SIMPLE_METHOD(0, idSize, recv); + } +} + +/** + @c optimize @e optimized succ @j 最適化された recv.succ()。 */ @@ -980,6 +980,7 @@ vm_init_redefined_flag(void) OP(AREF, AREF), (C(Array), C(Hash)); OP(ASET, ASET), (C(Array), C(Hash)); OP(Length, LENGTH), (C(Array), C(String), C(Hash)); + OP(Size, SIZE), (C(Array), C(String), C(Hash)); OP(Succ, SUCC), (C(Fixnum), C(String), C(Time)); OP(GT, GT), (C(Fixnum)); OP(GE, GE), (C(Fixnum)); diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 055c43c16a..bb4cef553b 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -48,6 +48,7 @@ enum { BOP_AREF, BOP_ASET, BOP_LENGTH, + BOP_SIZE, BOP_SUCC, BOP_GT, BOP_GE, |