* 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
This commit is contained in:
parent
1f75a4e700
commit
cd84310864
@ -1,3 +1,12 @@
|
|||||||
|
Tue Dec 18 20:58:35 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* 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 <ko1@atdot.net>
|
Tue Dec 18 18:10:05 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* bootstraptest/test_knownbug.rb: add issues.
|
* bootstraptest/test_knownbug.rb: add issues.
|
||||||
|
@ -628,3 +628,18 @@ assert_match /illegal multibyte char/, %q{
|
|||||||
STDERR.reopen(STDOUT)
|
STDERR.reopen(STDOUT)
|
||||||
eval("\"\xf0".force_encoding("utf-8"))
|
eval("\"\xf0".force_encoding("utf-8"))
|
||||||
}, '[ruby-dev:32429]'
|
}, '[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
compile.c
23
compile.c
@ -1416,6 +1416,21 @@ insn_set_specialized_instruction(INSN *iobj, int insn_id)
|
|||||||
return COMPILE_OK;
|
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
|
static int
|
||||||
iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
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) {
|
else if (mid == idSucc) {
|
||||||
insn_set_specialized_instruction(iobj, BIN(opt_succ));
|
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) {
|
else if (argc == 1) {
|
||||||
if (0) {
|
if (0) {
|
||||||
@ -1455,7 +1473,10 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
|||||||
insn_set_specialized_instruction(iobj, BIN(opt_mod));
|
insn_set_specialized_instruction(iobj, BIN(opt_mod));
|
||||||
}
|
}
|
||||||
else if (mid == idEq) {
|
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) {
|
else if (mid == idLT) {
|
||||||
insn_set_specialized_instruction(iobj, BIN(opt_lt));
|
insn_set_specialized_instruction(iobj, BIN(opt_lt));
|
||||||
|
2
id.c
2
id.c
@ -38,6 +38,8 @@ Init_id(void)
|
|||||||
idEqq = rb_intern("===");
|
idEqq = rb_intern("===");
|
||||||
idBackquote = rb_intern("`");
|
idBackquote = rb_intern("`");
|
||||||
idEqTilde = rb_intern("=~");
|
idEqTilde = rb_intern("=~");
|
||||||
|
idNot = rb_intern("!");
|
||||||
|
idNeq = rb_intern("!=");
|
||||||
|
|
||||||
idAREF = rb_intern("[]");
|
idAREF = rb_intern("[]");
|
||||||
idASET = rb_intern("[]=");
|
idASET = rb_intern("[]=");
|
||||||
|
2
id.h
2
id.h
@ -25,6 +25,8 @@ extern ID idGT;
|
|||||||
extern ID idGE;
|
extern ID idGE;
|
||||||
extern ID idEq;
|
extern ID idEq;
|
||||||
extern ID idEqq;
|
extern ID idEqq;
|
||||||
|
extern ID idNeq;
|
||||||
|
extern ID idNot;
|
||||||
extern ID idBackquote;
|
extern ID idBackquote;
|
||||||
extern ID idEqTilde;
|
extern ID idEqTilde;
|
||||||
extern ID idThrowState;
|
extern ID idThrowState;
|
||||||
|
@ -1404,3 +1404,66 @@ call_end_proc(VALUE data)
|
|||||||
{
|
{
|
||||||
rb_proc_call(data, rb_ary_new2(0));
|
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;
|
||||||
|
}
|
||||||
|
121
insns.def
121
insns.def
@ -581,26 +581,6 @@ newrange
|
|||||||
val = rb_range_new(low, high, flag);
|
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 */
|
/* deal with stack operation */
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
@ -1655,51 +1635,13 @@ opt_mod
|
|||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_eq
|
opt_eq
|
||||||
()
|
(IC ic)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
if (FIXNUM_2_P(recv, obj) &&
|
val = opt_eq_func(recv, obj, ic);
|
||||||
BASIC_OP_UNREDEFINED_P(BOP_EQ)) {
|
|
||||||
long a = FIX2LONG(recv), b = FIX2LONG(obj);
|
|
||||||
|
|
||||||
if (a == b) {
|
if (val == Qundef) {
|
||||||
val = Qtrue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val = Qfalse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
INSN_LABEL(normal_dispatch):
|
|
||||||
/* other */
|
/* other */
|
||||||
PUSH(recv);
|
PUSH(recv);
|
||||||
PUSH(obj);
|
PUSH(obj);
|
||||||
@ -1707,6 +1649,36 @@ opt_eq
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val == Qundef) {
|
||||||
|
/* other */
|
||||||
|
PUSH(recv);
|
||||||
|
PUSH(obj);
|
||||||
|
CALL_SIMPLE_METHOD(1, idNeq, recv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@c optimize
|
@c optimize
|
||||||
@ -1991,7 +1963,8 @@ opt_succ
|
|||||||
BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
|
BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
|
||||||
val = rb_time_succ(recv);
|
val = rb_time_succ(recv);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
goto INSN_LABEL(normal_dispatch);
|
goto INSN_LABEL(normal_dispatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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
|
@c optimize
|
||||||
@e optimized regexp match
|
@e optimized regexp match
|
||||||
|
6
object.c
6
object.c
@ -89,7 +89,7 @@ rb_eql(VALUE obj1, VALUE obj2)
|
|||||||
* 1.eql? 1.0 #=> false
|
* 1.eql? 1.0 #=> false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
rb_obj_equal(VALUE obj1, VALUE obj2)
|
rb_obj_equal(VALUE obj1, VALUE obj2)
|
||||||
{
|
{
|
||||||
if (obj1 == obj2) return Qtrue;
|
if (obj1 == obj2) return Qtrue;
|
||||||
@ -103,7 +103,7 @@ rb_obj_equal(VALUE obj1, VALUE obj2)
|
|||||||
* Boolean negate.
|
* Boolean negate.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
rb_obj_not(VALUE obj)
|
rb_obj_not(VALUE obj)
|
||||||
{
|
{
|
||||||
return RTEST(obj) ? Qfalse : Qtrue;
|
return RTEST(obj) ? Qfalse : Qtrue;
|
||||||
@ -116,7 +116,7 @@ rb_obj_not(VALUE obj)
|
|||||||
* Returns true if two objects are not-equal, otherwise false.
|
* Returns true if two objects are not-equal, otherwise false.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
rb_obj_not_equal(VALUE obj1, VALUE obj2)
|
rb_obj_not_equal(VALUE obj1, VALUE obj2)
|
||||||
{
|
{
|
||||||
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
|
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user