diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-18 12:07:51 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-18 12:07:51 +0000 |
commit | cd843108646b999e13cfbf04e51eca30b68850b3 (patch) | |
tree | eb87ffe59f0f71747be4fc76d84244c414e3e3da | |
parent | 1f75a4e700883da8d15048fc3da6528ba53ec1e4 (diff) |
* compile.c, insnhelper.ci, insns.def, object.c, vm.c, vm.h:
optimize !@, != method invocation.
* id.c, id.h: ditto.
* bootstraptest/test_syntax.rb: add tests for above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14299 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | bootstraptest/test_syntax.rb | 15 | ||||
-rw-r--r-- | compile.c | 23 | ||||
-rw-r--r-- | id.c | 2 | ||||
-rw-r--r-- | id.h | 2 | ||||
-rw-r--r-- | insnhelper.ci | 63 | ||||
-rw-r--r-- | insns.def | 117 | ||||
-rw-r--r-- | object.c | 6 | ||||
-rw-r--r-- | vm.h | 2 |
9 files changed, 175 insertions, 64 deletions
@@ -1,3 +1,12 @@ +Tue Dec 18 20:58:35 2007 Koichi Sasada <[email protected]> + + * compile.c, insnhelper.ci, insns.def, object.c, vm.c, vm.h: + optimize !@, != method invocation. + + * id.c, id.h: ditto. + + * bootstraptest/test_syntax.rb: add tests for above. + Tue Dec 18 18:10:05 2007 Koichi Sasada <[email protected]> * bootstraptest/test_knownbug.rb: add issues. diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb index 3e4c79bece..0ba8f658f2 100644 --- a/bootstraptest/test_syntax.rb +++ b/bootstraptest/test_syntax.rb @@ -628,3 +628,18 @@ assert_match /illegal multibyte char/, %q{ STDERR.reopen(STDOUT) eval("\"\xf0".force_encoding("utf-8")) }, '[ruby-dev:32429]' + +# method ! and != +assert_equal 'true', %q{!false} +assert_equal 'true', %q{1 == 1} +assert_equal 'true', %q{1 != 2} +assert_equal 'true', %q{ + class C; def !=(obj); true; end; end + C.new != 1 +} +assert_equal 'true', %q{ + class C; def !@; true; end; end + !C.new +} + + @@ -1416,6 +1416,21 @@ insn_set_specialized_instruction(INSN *iobj, int insn_id) return COMPILE_OK; } +static int +insn_set_specialized_instruction_with_ic(INSN *iobj, int insn_id, int n) +{ + int i; + iobj->insn_id = insn_id; + iobj->operand_size = n; + + /* max of n is 4 */ + for (i=0; i<n; i++) { + iobj->operands[i] = Qnil; + } + + return COMPILE_OK; +} + static int iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) @@ -1435,6 +1450,9 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) else if (mid == idSucc) { insn_set_specialized_instruction(iobj, BIN(opt_succ)); } + else if (mid == idNot) { + insn_set_specialized_instruction_with_ic(iobj, BIN(opt_not), 1); + } } else if (argc == 1) { if (0) { @@ -1455,7 +1473,10 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) insn_set_specialized_instruction(iobj, BIN(opt_mod)); } else if (mid == idEq) { - insn_set_specialized_instruction(iobj, BIN(opt_eq)); + insn_set_specialized_instruction_with_ic(iobj, BIN(opt_eq), 1); + } + else if (mid == idNeq) { + insn_set_specialized_instruction_with_ic(iobj, BIN(opt_neq), 2); } else if (mid == idLT) { insn_set_specialized_instruction(iobj, BIN(opt_lt)); @@ -38,6 +38,8 @@ Init_id(void) idEqq = rb_intern("==="); idBackquote = rb_intern("`"); idEqTilde = rb_intern("=~"); + idNot = rb_intern("!"); + idNeq = rb_intern("!="); idAREF = rb_intern("[]"); idASET = rb_intern("[]="); @@ -25,6 +25,8 @@ extern ID idGT; extern ID idGE; extern ID idEq; extern ID idEqq; +extern ID idNeq; +extern ID idNot; extern ID idBackquote; extern ID idEqTilde; extern ID idThrowState; diff --git a/insnhelper.ci b/insnhelper.ci index f7a3a0c3d2..4197f3b06b 100644 --- a/insnhelper.ci +++ b/insnhelper.ci @@ -1404,3 +1404,66 @@ call_end_proc(VALUE data) { rb_proc_call(data, rb_ary_new2(0)); } + +static inline int +check_cfunc(NODE *mn, void *func) +{ + if (mn && nd_type(mn->nd_body) == NODE_CFUNC && + mn->nd_body->nd_cfnc == func) { + return 1; + } + else { + return 0; + } +} + +static VALUE +opt_eq_func(VALUE recv, VALUE obj, IC ic) +{ + VALUE val = Qundef; + + if (FIXNUM_2_P(recv, obj) && + BASIC_OP_UNREDEFINED_P(BOP_EQ)) { + long a = FIX2LONG(recv), b = FIX2LONG(obj); + + if (a == b) { + val = Qtrue; + } + else { + val = Qfalse; + } + } + else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) { + if (HEAP_CLASS_OF(recv) == rb_cFloat && + HEAP_CLASS_OF(obj) == rb_cFloat && + BASIC_OP_UNREDEFINED_P(BOP_EQ)) { + double a = RFLOAT_VALUE(recv); + double b = RFLOAT_VALUE(obj); + + if (isnan(a) || isnan(b)) { + val = Qfalse; + } + else if (a == b) { + val = Qtrue; + } + else { + val = Qfalse; + } + } + else if (HEAP_CLASS_OF(recv) == rb_cString && + HEAP_CLASS_OF(obj) == rb_cString && + BASIC_OP_UNREDEFINED_P(BOP_EQ)) { + val = rb_str_equal(recv, obj); + } + else { + NODE *mn = vm_method_search(idEq, CLASS_OF(recv), ic); + extern VALUE rb_obj_equal(VALUE obj1, VALUE obj2); + + if (check_cfunc(mn, rb_obj_equal)) { + return recv == obj ? Qtrue : Qfalse; + } + } + } + + return val; +} @@ -581,26 +581,6 @@ newrange val = rb_range_new(low, high, flag); } -/** - @c put - @e put !val. - @j !val �̌��ʂ��X�^�b�N�Ƀv�b�V������B - */ -DEFINE_INSN -putnot -() -(VALUE obj) -(VALUE val) -{ - if (RTEST(obj)) { - val = Qfalse; - } - else { - val = Qtrue; - } -} - - /**********************************************************/ /* deal with stack operation */ /**********************************************************/ @@ -1655,59 +1635,51 @@ opt_mod */ DEFINE_INSN opt_eq -() +(IC ic) (VALUE recv, VALUE obj) (VALUE val) { - if (FIXNUM_2_P(recv, obj) && - BASIC_OP_UNREDEFINED_P(BOP_EQ)) { - long a = FIX2LONG(recv), b = FIX2LONG(obj); + val = opt_eq_func(recv, obj, ic); - if (a == b) { - val = Qtrue; - } - else { - val = Qfalse; - } + if (val == Qundef) { + /* other */ + PUSH(recv); + PUSH(obj); + CALL_SIMPLE_METHOD(1, idEq, recv); } - else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) { - if (0) { - } - else if (HEAP_CLASS_OF(recv) == rb_cFloat && - HEAP_CLASS_OF(obj) == rb_cFloat && - BASIC_OP_UNREDEFINED_P(BOP_EQ)) { - double a = RFLOAT_VALUE(recv); - double b = RFLOAT_VALUE(obj); +} - if (isnan(a) || isnan(b)) { - val = Qfalse; - } - else if (a == b) { - val = Qtrue; - } - else { - val = Qfalse; - } - } - else if (HEAP_CLASS_OF(recv) == rb_cString && - HEAP_CLASS_OF(obj) == rb_cString && - BASIC_OP_UNREDEFINED_P(BOP_EQ)) { - val = rb_str_equal(recv, obj); - } - else { - goto INSN_LABEL(normal_dispatch); +/** + @c optimize + @e optimized X!=Y. + @j �œK�����ꂽ X!=Y�B + */ +DEFINE_INSN +opt_neq +(IC ic1, IC ic2) +(VALUE recv, VALUE obj) +(VALUE val) +{ + extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2); + NODE *mn = vm_method_search(idNeq, CLASS_OF(recv), ic1); + val = Qundef; + + if (check_cfunc(mn, rb_obj_not_equal)) { + val = opt_eq_func(recv, obj, ic2); + + if (val != Qundef) { + val = RTEST(val) ? Qfalse : Qtrue; } } - else { - INSN_LABEL(normal_dispatch): + + if (val == Qundef) { /* other */ PUSH(recv); PUSH(obj); - CALL_SIMPLE_METHOD(1, idEq, recv); + CALL_SIMPLE_METHOD(1, idNeq, recv); } } - /** @c optimize @e optimized X<Y. @@ -1991,7 +1963,8 @@ opt_succ BASIC_OP_UNREDEFINED_P(BOP_SUCC)) { val = rb_time_succ(recv); } - else { + else + { goto INSN_LABEL(normal_dispatch); } } @@ -2004,6 +1977,30 @@ opt_succ /** @c optimize + @e optimized not + @j �œK�����ꂽ recv.!()�B + */ +DEFINE_INSN +opt_not +(IC ic) +(VALUE recv) +(VALUE val) +{ + extern VALUE rb_obj_not(VALUE obj); + NODE *mn = vm_method_search(idNot, CLASS_OF(recv), ic); + + if (check_cfunc(mn, rb_obj_not)) { + val = RTEST(recv) ? Qfalse : Qtrue; + } + else { + PUSH(recv); + CALL_SIMPLE_METHOD(0, idNot, recv); + } +} + + +/** + @c optimize @e optimized regexp match @j �œK�����ꂽ���K�\���}�b�`�B */ @@ -89,7 +89,7 @@ rb_eql(VALUE obj1, VALUE obj2) * 1.eql? 1.0 #=> false */ -static VALUE +VALUE rb_obj_equal(VALUE obj1, VALUE obj2) { if (obj1 == obj2) return Qtrue; @@ -103,7 +103,7 @@ rb_obj_equal(VALUE obj1, VALUE obj2) * Boolean negate. */ -static VALUE +VALUE rb_obj_not(VALUE obj) { return RTEST(obj) ? Qfalse : Qtrue; @@ -116,7 +116,7 @@ rb_obj_not(VALUE obj) * Returns true if two objects are not-equal, otherwise false. */ -static VALUE +VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2) { VALUE result = rb_funcall(obj1, id_eq, 1, obj2); @@ -279,5 +279,7 @@ default: \ #define BOP_SUCC 0x1000 #define BOP_GT 0x2000 #define BOP_GE 0x4000 +#define BOP_NOT 0x8000 +#define BOP_NEQ 0x10000 #endif /* RUBY_VM_H */ |