diff --git a/ChangeLog b/ChangeLog index d980868eb8f1d8..dd7b9c9c16d11c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sun Sep 6 17:31:28 2009 Koichi Sasada + + * 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 * insns.def (setinstancevariable), vm_insnhelper.c (vm_setivar): diff --git a/compile.c b/compile.c index 42828a802b8a20..d3c26671a620be 100644 --- a/compile.c +++ b/compile.c @@ -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)); } diff --git a/id.c b/id.c index 4fd760af0314c6..2111751a37619a 100644 --- a/id.c +++ b/id.c @@ -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"); diff --git a/id.h b/id.h index 1f94dbb9963448..8087683cf5c8e6 100644 --- a/id.h +++ b/id.h @@ -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), diff --git a/insns.def b/insns.def index 98febf89b85030..7de873d4bf155e 100644 --- a/insns.def +++ b/insns.def @@ -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); } @@ -1943,6 +1943,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 diff --git a/vm.c b/vm.c index 4af968653df3fd..c794b08dcf102f 100644 --- a/vm.c +++ b/vm.c @@ -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 055c43c16ad99e..bb4cef553b6934 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,