mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37036 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
24793ac32d
commit
1bebb22ce1
8 changed files with 74 additions and 0 deletions
13
ChangeLog
13
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>
|
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
|
* insns.def (invokesuper): klass in cfp is not valid in at_exit and
|
||||||
|
|
|
@ -1872,6 +1872,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
||||||
switch (mid) {
|
switch (mid) {
|
||||||
case idLength: SP_INSN(length); break;
|
case idLength: SP_INSN(length); break;
|
||||||
case idSize: SP_INSN(size); break;
|
case idSize: SP_INSN(size); break;
|
||||||
|
case idEmptyP: SP_INSN(empty_p);break;
|
||||||
case idSucc: SP_INSN(succ); break;
|
case idSucc: SP_INSN(succ); break;
|
||||||
case idNot: SP_INSN(not); break;
|
case idNot: SP_INSN(not); break;
|
||||||
}
|
}
|
||||||
|
|
1
id.c
1
id.c
|
@ -41,6 +41,7 @@ Init_id(void)
|
||||||
REGISTER_SYMID(idEach, "each");
|
REGISTER_SYMID(idEach, "each");
|
||||||
REGISTER_SYMID(idLength, "length");
|
REGISTER_SYMID(idLength, "length");
|
||||||
REGISTER_SYMID(idSize, "size");
|
REGISTER_SYMID(idSize, "size");
|
||||||
|
REGISTER_SYMID(idEmptyP, "empty?");
|
||||||
REGISTER_SYMID(idLambda, "lambda");
|
REGISTER_SYMID(idLambda, "lambda");
|
||||||
REGISTER_SYMID(idIntern, "intern");
|
REGISTER_SYMID(idIntern, "intern");
|
||||||
REGISTER_SYMID(idGets, "gets");
|
REGISTER_SYMID(idGets, "gets");
|
||||||
|
|
38
insns.def
38
insns.def
|
@ -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
|
@c optimize
|
||||||
@e optimized succ
|
@e optimized succ
|
||||||
|
|
|
@ -20,6 +20,7 @@ method_ids = %w[
|
||||||
MethodMissing
|
MethodMissing
|
||||||
Length
|
Length
|
||||||
Size
|
Size
|
||||||
|
EmptyP
|
||||||
Gets
|
Gets
|
||||||
Succ
|
Succ
|
||||||
Each
|
Each
|
||||||
|
|
|
@ -85,6 +85,14 @@ class TestRubyOptimization < Test::Unit::TestCase
|
||||||
assert_equal 6, "string".length
|
assert_equal 6, "string".length
|
||||||
end
|
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
|
def test_string_plus
|
||||||
assert_equal "", "" + ""
|
assert_equal "", "" + ""
|
||||||
assert_equal "x", "x" + ""
|
assert_equal "x", "x" + ""
|
||||||
|
@ -116,11 +124,21 @@ class TestRubyOptimization < Test::Unit::TestCase
|
||||||
assert_equal 3, [1,2,3].length
|
assert_equal 3, [1,2,3].length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_array_empty?
|
||||||
|
assert_equal true, [].empty?
|
||||||
|
assert_equal false, [1,2,3].empty?
|
||||||
|
end
|
||||||
|
|
||||||
def test_hash_length
|
def test_hash_length
|
||||||
assert_equal 0, {}.length
|
assert_equal 0, {}.length
|
||||||
assert_equal 1, {1=>1}.length
|
assert_equal 1, {1=>1}.length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_hash_empty?
|
||||||
|
assert_equal true, {}.empty?
|
||||||
|
assert_equal false, {1=>1}.empty?
|
||||||
|
end
|
||||||
|
|
||||||
class MyObj
|
class MyObj
|
||||||
def ==(other)
|
def ==(other)
|
||||||
true
|
true
|
||||||
|
|
1
vm.c
1
vm.c
|
@ -1005,6 +1005,7 @@ vm_init_redefined_flag(void)
|
||||||
OP(ASET, ASET), (C(Array), C(Hash));
|
OP(ASET, ASET), (C(Array), C(Hash));
|
||||||
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
|
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
|
||||||
OP(Size, SIZE), (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));
|
OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
|
||||||
#undef C
|
#undef C
|
||||||
#undef OP
|
#undef OP
|
||||||
|
|
|
@ -49,6 +49,7 @@ enum {
|
||||||
BOP_ASET,
|
BOP_ASET,
|
||||||
BOP_LENGTH,
|
BOP_LENGTH,
|
||||||
BOP_SIZE,
|
BOP_SIZE,
|
||||||
|
BOP_EMPTY_P,
|
||||||
BOP_SUCC,
|
BOP_SUCC,
|
||||||
BOP_GT,
|
BOP_GT,
|
||||||
BOP_GE,
|
BOP_GE,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue