ruby-changes:45712
From: nobu <ko1@a...>
Date: Mon, 6 Mar 2017 15:44:15 +0900 (JST)
Subject: [ruby-changes:45712] nobu:r57785 (trunk): opt_eq_func refactor
nobu 2017-03-06 15:44:11 +0900 (Mon, 06 Mar 2017) New Revision: 57785 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57785 Log: opt_eq_func refactor * vm_insnhelper.c (opt_eq_func): method to dispatch is resolved by only the receiver's class, not including the argument class. even if basic operation is redefined, other class conditions never meet. optimize Float and non-Float case, delegate to rb_float_equal directly. Modified files: trunk/internal.h trunk/numeric.c trunk/vm_insnhelper.c Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 57784) +++ vm_insnhelper.c (revision 57785) @@ -1265,32 +1265,29 @@ inline https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1265 VALUE opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc) { - if (FIXNUM_2_P(recv, obj) && - BASIC_OP_UNREDEFINED_P(BOP_EQ, INTEGER_REDEFINED_OP_FLAG)) { - return (recv == obj) ? Qtrue : Qfalse; +#define BUILTIN_CLASS_P(x, k) (!SPECIAL_CONST_P(x) && RBASIC_CLASS(x) == k) +#define EQ_UNREDEFINED_P(t) BASIC_OP_UNREDEFINED_P(BOP_EQ, t##_REDEFINED_OP_FLAG) + if (FIXNUM_2_P(recv, obj)) { + if (EQ_UNREDEFINED_P(INTEGER)) { + return (recv == obj) ? Qtrue : Qfalse; + } } - else if (FLONUM_2_P(recv, obj) && - BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) { - return (recv == obj) ? Qtrue : Qfalse; + else if (FLONUM_2_P(recv, obj)) { + if (EQ_UNREDEFINED_P(FLOAT)) { + return (recv == obj) ? Qtrue : Qfalse; + } } - else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) { - if (RBASIC_CLASS(recv) == rb_cFloat && - RBASIC_CLASS(obj) == rb_cFloat && - BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) { - double a = RFLOAT_VALUE(recv); - double b = RFLOAT_VALUE(obj); - - if (isnan(a) || isnan(b)) { - return Qfalse; - } - return (a == b) ? Qtrue : Qfalse; + else if (BUILTIN_CLASS_P(recv, rb_cFloat)) { + if (EQ_UNREDEFINED_P(FLOAT)) { + return rb_float_equal(recv, obj); } - else if (RBASIC_CLASS(recv) == rb_cString && - RBASIC_CLASS(obj) == rb_cString && - BASIC_OP_UNREDEFINED_P(BOP_EQ, STRING_REDEFINED_OP_FLAG)) { + } + else if (BUILTIN_CLASS_P(recv, rb_cString)) { + if (EQ_UNREDEFINED_P(STRING)) { return rb_str_equal(recv, obj); } } +#undef EQ_UNREDEFINED_P { vm_search_method(ci, cc, recv); Index: internal.h =================================================================== --- internal.h (revision 57784) +++ internal.h (revision 57785) @@ -1307,6 +1307,7 @@ VALUE rb_int_lshift(VALUE x, VALUE y); https://github.com/ruby/ruby/blob/trunk/internal.h#L1307 VALUE rb_int_div(VALUE x, VALUE y); VALUE rb_int_abs(VALUE num); VALUE rb_float_abs(VALUE flt); +VALUE rb_float_equal(VALUE x, VALUE y); #if USE_FLONUM #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n))) Index: numeric.c =================================================================== --- numeric.c (revision 57784) +++ numeric.c (revision 57785) @@ -1418,8 +1418,8 @@ num_equal(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1418 * */ -static VALUE -flo_eq(VALUE x, VALUE y) +VALUE +rb_float_equal(VALUE x, VALUE y) { volatile double a, b; @@ -1442,6 +1442,8 @@ flo_eq(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1442 return (a == b)?Qtrue:Qfalse; } +#define flo_eq rb_float_equal + /* * call-seq: * float.hash -> integer -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/