Skip to content

Commit

Permalink
* insns.def: add new instruction opt_empty_p' for optimize empty?'
Browse files Browse the repository at this point in the history
  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.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37036 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
ko1 committed Sep 26, 2012
1 parent 24793ac commit 1bebb22
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 0 deletions.
13 changes: 13 additions & 0 deletions ChangeLog
@@ -1,3 +1,16 @@
Wed Sep 26 16:39:57 2012 Koichi Sasada <ko1@atdot.net>

* 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@ruby-lang.org>

* insns.def (invokesuper): klass in cfp is not valid in at_exit and
Expand Down
1 change: 1 addition & 0 deletions compile.c
Expand Up @@ -1872,6 +1872,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
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;
}
Expand Down
1 change: 1 addition & 0 deletions id.c
Expand Up @@ -41,6 +41,7 @@ Init_id(void)
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");
Expand Down
38 changes: 38 additions & 0 deletions insns.def
Expand Up @@ -1992,6 +1992,44 @@ opt_size
}
}

/**
@c optimize
@e optimized empty?
@j 最適化された 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
Expand Down
1 change: 1 addition & 0 deletions template/id.h.tmpl
Expand Up @@ -20,6 +20,7 @@ method_ids = %w[
MethodMissing
Length
Size
EmptyP
Gets
Succ
Each
Expand Down
18 changes: 18 additions & 0 deletions test/ruby/test_optimization.rb
Expand Up @@ -85,6 +85,14 @@ def test_string_length
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" + ""
Expand Down Expand Up @@ -116,11 +124,21 @@ def test_array_length
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
Expand Down
1 change: 1 addition & 0 deletions vm.c
Expand Up @@ -1005,6 +1005,7 @@ vm_init_redefined_flag(void)
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
Expand Down
1 change: 1 addition & 0 deletions vm_insnhelper.h
Expand Up @@ -49,6 +49,7 @@ enum {
BOP_ASET,
BOP_LENGTH,
BOP_SIZE,
BOP_EMPTY_P,
BOP_SUCC,
BOP_GT,
BOP_GE,
Expand Down

0 comments on commit 1bebb22

Please sign in to comment.