ruby-changes:24984
From: ko1 <ko1@a...>
Date: Wed, 26 Sep 2012 18:35:01 +0900 (JST)
Subject: [ruby-changes:24984] ko1:r37036 (trunk): * insns.def: add new instruction `opt_empty_p' for optimize `empty?'
ko1 2012-09-26 18:34:46 +0900 (Wed, 26 Sep 2012) New Revision: 37036 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37036 Log: * insns.def: add new instruction `opt_empty_p' for optimize `empty?' method. Apply a patch proposed at [ruby-dev:46120] [ruby-trunk - Feature #6972] by Glass_saga (Masaki Matsushita). * compile.c (iseq_specialized_instruction), vm.c, vm_insnhelper.h: ditto. * id.c, template/id.h.tmpl: ditto. * test/ruby/test_optimization.rb: test for this changes. Modified files: trunk/ChangeLog trunk/compile.c trunk/id.c trunk/insns.def trunk/template/id.h.tmpl trunk/test/ruby/test_optimization.rb trunk/vm.c trunk/vm_insnhelper.h Index: ChangeLog =================================================================== --- ChangeLog (revision 37035) +++ ChangeLog (revision 37036) @@ -1,3 +1,16 @@ +Wed Sep 26 16:39:57 2012 Koichi Sasada <ko1@a...> + + * insns.def: add new instruction `opt_empty_p' for optimize `empty?' + method. Apply a patch proposed at [ruby-dev:46120] + [ruby-trunk - Feature #6972] by Glass_saga (Masaki Matsushita). + + * compile.c (iseq_specialized_instruction), vm.c, vm_insnhelper.h: + ditto. + + * id.c, template/id.h.tmpl: ditto. + + * test/ruby/test_optimization.rb: test for this changes. + Tue Sep 25 09:59:26 2012 Nobuyoshi Nakada <nobu@r...> * insns.def (invokesuper): klass in cfp is not valid in at_exit and Index: insns.def =================================================================== --- insns.def (revision 37035) +++ insns.def (revision 37036) @@ -1994,6 +1994,44 @@ /** @c optimize + @e optimized empty? + @j i recv.empty?()+ */ +DEFINE_INSN +opt_empty_p +(IC ic) +(VALUE recv) +(VALUE val) +{ + if (!SPECIAL_CONST_P(recv)) { + if (HEAP_CLASS_OF(recv) == rb_cString && + BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, STRING_REDEFINED_OP_FLAG)) { + if (RSTRING_LEN(recv) == 0) val = Qtrue; + else val = Qfalse; + } + else if (HEAP_CLASS_OF(recv) == rb_cArray && + BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, ARRAY_REDEFINED_OP_FLAG)) { + if (RARRAY_LEN(recv) == 0) val = Qtrue; + else val = Qfalse; + } + else if (HEAP_CLASS_OF(recv) == rb_cHash && + BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, HASH_REDEFINED_OP_FLAG)) { + if (RHASH_EMPTY_P(recv)) val = Qtrue; + else val = Qfalse; + } + else { + goto INSN_LABEL(normal_dispatch); + } + } + else { + INSN_LABEL(normal_dispatch): + PUSH(recv); + CALL_SIMPLE_METHOD(0, idEmptyP, recv); + } +} + +/** + @c optimize @e optimized succ @j i recv.succ() */ Index: compile.c =================================================================== --- compile.c (revision 37035) +++ compile.c (revision 37036) @@ -1872,6 +1872,7 @@ switch (mid) { case idLength: SP_INSN(length); break; case idSize: SP_INSN(size); break; + case idEmptyP: SP_INSN(empty_p);break; case idSucc: SP_INSN(succ); break; case idNot: SP_INSN(not); break; } Index: id.c =================================================================== --- id.c (revision 37035) +++ id.c (revision 37036) @@ -41,6 +41,7 @@ REGISTER_SYMID(idEach, "each"); REGISTER_SYMID(idLength, "length"); REGISTER_SYMID(idSize, "size"); + REGISTER_SYMID(idEmptyP, "empty?"); REGISTER_SYMID(idLambda, "lambda"); REGISTER_SYMID(idIntern, "intern"); REGISTER_SYMID(idGets, "gets"); Index: vm.c =================================================================== --- vm.c (revision 37035) +++ vm.c (revision 37036) @@ -1005,6 +1005,7 @@ 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(EmptyP, EMPTY_P), (C(Array), C(String), C(Hash)); OP(Succ, SUCC), (C(Fixnum), C(String), C(Time)); #undef C #undef OP Index: vm_insnhelper.h =================================================================== --- vm_insnhelper.h (revision 37035) +++ vm_insnhelper.h (revision 37036) @@ -49,6 +49,7 @@ BOP_ASET, BOP_LENGTH, BOP_SIZE, + BOP_EMPTY_P, BOP_SUCC, BOP_GT, BOP_GE, Index: test/ruby/test_optimization.rb =================================================================== --- test/ruby/test_optimization.rb (revision 37035) +++ test/ruby/test_optimization.rb (revision 37036) @@ -85,6 +85,14 @@ assert_equal 6, "string".length end + def test_string_empty? + assert_equal true, "".empty? + assert_equal false, "string".empty? + assert_nil redefine_method('String', 'empty?') { "string".empty? } + assert_equal true, "".empty? + assert_equal false, "string".empty? + end + def test_string_plus assert_equal "", "" + "" assert_equal "x", "x" + "" @@ -116,11 +124,21 @@ assert_equal 3, [1,2,3].length end + def test_array_empty? + assert_equal true, [].empty? + assert_equal false, [1,2,3].empty? + end + def test_hash_length assert_equal 0, {}.length assert_equal 1, {1=>1}.length end + def test_hash_empty? + assert_equal true, {}.empty? + assert_equal false, {1=>1}.empty? + end + class MyObj def ==(other) true Index: template/id.h.tmpl =================================================================== --- template/id.h.tmpl (revision 37035) +++ template/id.h.tmpl (revision 37036) @@ -20,6 +20,7 @@ MethodMissing Length Size + EmptyP Gets Succ Each -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/