Skip to content

Commit

Permalink
* compile.c, insnhelper.ci, insns.def, object.c, vm.c, vm.h:
Browse files Browse the repository at this point in the history
  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
  • Loading branch information
ko1 committed Dec 18, 2007
1 parent 1f75a4e commit cd84310
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 64 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
15 changes: 15 additions & 0 deletions bootstraptest/test_syntax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,18 @@ class << (ary=[]); def []; 0; end; def []=(x); super(0,x);end;end; ary[]+=1
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
}


23 changes: 22 additions & 1 deletion compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -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));
Expand Down
2 changes: 2 additions & 0 deletions id.c
Original file line number Diff line number Diff line change
Expand Up @@ -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("[]=");
Expand Down
2 changes: 2 additions & 0 deletions id.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
63 changes: 63 additions & 0 deletions insnhelper.ci
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
117 changes: 57 additions & 60 deletions insns.def
Original file line number Diff line number Diff line change
Expand Up @@ -581,26 +581,6 @@ newrange
val = rb_range_new(low, high, flag);
}

/**
@c put
@e put !val.
@j !val の結果をスタックにプッシュする。
*/
DEFINE_INSN
putnot
()
(VALUE obj)
(VALUE val)
{
if (RTEST(obj)) {
val = Qfalse;
}
else {
val = Qtrue;
}
}


/**********************************************************/
/* deal with stack operation */
/**********************************************************/
Expand Down Expand Up @@ -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 最適化された X!=Y。
*/
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.
Expand Down Expand Up @@ -1991,7 +1963,8 @@ opt_succ
BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
val = rb_time_succ(recv);
}
else {
else
{
goto INSN_LABEL(normal_dispatch);
}
}
Expand All @@ -2002,6 +1975,30 @@ opt_succ
}
}

/**
@c optimize
@e optimized not
@j 最適化された recv.!()。
*/
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
Expand Down
6 changes: 3 additions & 3 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit cd84310

Please sign in to comment.