ruby-changes:61869
From: Takashi <ko1@a...>
Date: Sun, 21 Jun 2020 06:55:28 +0900 (JST)
Subject: [ruby-changes:61869] 95b0fed371 (master): Make Integer#zero? a separated method and builtin (#3226)
https://git.ruby-lang.org/ruby.git/commit/?id=95b0fed371 From 95b0fed3714b87dcb40a16f33d9e3160f9945e38 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Sat, 20 Jun 2020 14:55:09 -0700 Subject: Make Integer#zero? a separated method and builtin (#3226) A prerequisite to fix https://bugs.ruby-lang.org/issues/15589 with JIT. This commit alone doesn't make a significant difference yet, but I thought this commit should be committed independently. This method override was discussed in [Misc #16961]. diff --git a/.document b/.document index b18ca80..0e0969a 100644 --- a/.document +++ b/.document @@ -14,6 +14,7 @@ array.rb https://github.com/ruby/ruby/blob/trunk/.document#L14 ast.rb dir.rb gc.rb +integer.rb io.rb kernel.rb pack.rb diff --git a/NEWS.md b/NEWS.md index c69321d..ac6c6de 100644 --- a/NEWS.md +++ b/NEWS.md @@ -214,6 +214,8 @@ Excluding feature bug fixes. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L214 * The issues of sdbm will handle at https://github.com/ruby/sdbm +* `Integer#zero?` overrides `Numeric#zero?` for optimization. + ## Stdlib compatibility issues Excluding feature bug fixes. diff --git a/benchmark/num_zero_p.yml b/benchmark/num_zero_p.yml new file mode 100644 index 0000000..2195963 --- /dev/null +++ b/benchmark/num_zero_p.yml @@ -0,0 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/num_zero_p.yml#L1 +benchmark: + - 0.zero? + - 1.zero? + - 0r.zero? + - 1r.zero? + - 0i.zero? + - 1i.zero? +loop_count: 50000000 diff --git a/common.mk b/common.mk index 3a54b0e..7f4e026 100644 --- a/common.mk +++ b/common.mk @@ -1008,6 +1008,7 @@ $(srcs_vpath)mjit_compile.inc: $(tooldir)/ruby_vm/views/mjit_compile.inc.erb $(i https://github.com/ruby/ruby/blob/trunk/common.mk#L1008 BUILTIN_RB_SRCS = \ $(srcdir)/ast.rb \ $(srcdir)/gc.rb \ + $(srcdir)/integer.rb \ $(srcdir)/io.rb \ $(srcdir)/dir.rb \ $(srcdir)/pack.rb \ @@ -8087,6 +8088,7 @@ miniinit.$(OBJEXT): {$(VPATH)}encoding.h https://github.com/ruby/ruby/blob/trunk/common.mk#L8088 miniinit.$(OBJEXT): {$(VPATH)}gc.rb miniinit.$(OBJEXT): {$(VPATH)}gem_prelude.rb miniinit.$(OBJEXT): {$(VPATH)}id.h +miniinit.$(OBJEXT): {$(VPATH)}integer.rb miniinit.$(OBJEXT): {$(VPATH)}intern.h miniinit.$(OBJEXT): {$(VPATH)}internal.h miniinit.$(OBJEXT): {$(VPATH)}internal/anyargs.h @@ -8921,12 +8923,15 @@ numeric.$(OBJEXT): {$(VPATH)}backward/2/r_cast.h https://github.com/ruby/ruby/blob/trunk/common.mk#L8923 numeric.$(OBJEXT): {$(VPATH)}backward/2/rmodule.h numeric.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h numeric.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h +numeric.$(OBJEXT): {$(VPATH)}builtin.h numeric.$(OBJEXT): {$(VPATH)}config.h numeric.$(OBJEXT): {$(VPATH)}constant.h numeric.$(OBJEXT): {$(VPATH)}defines.h numeric.$(OBJEXT): {$(VPATH)}encoding.h numeric.$(OBJEXT): {$(VPATH)}id.h numeric.$(OBJEXT): {$(VPATH)}id_table.h +numeric.$(OBJEXT): {$(VPATH)}integer.rb +numeric.$(OBJEXT): {$(VPATH)}integer.rbinc numeric.$(OBJEXT): {$(VPATH)}intern.h numeric.$(OBJEXT): {$(VPATH)}internal.h numeric.$(OBJEXT): {$(VPATH)}internal/anyargs.h diff --git a/inits.c b/inits.c index 4e5d65a..ad57b75 100644 --- a/inits.c +++ b/inits.c @@ -82,6 +82,7 @@ rb_call_builtin_inits(void) https://github.com/ruby/ruby/blob/trunk/inits.c#L82 { #define BUILTIN(n) CALL(builtin_##n) BUILTIN(gc); + BUILTIN(integer); BUILTIN(io); BUILTIN(dir); BUILTIN(ast); diff --git a/integer.rb b/integer.rb new file mode 100644 index 0000000..2fd32ea --- /dev/null +++ b/integer.rb @@ -0,0 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/integer.rb#L1 +class Integer + # call-seq: + # int.zero? -> true or false + # + # Returns +true+ if +num+ has a zero value. + def zero? + Primitive.cexpr! 'int_zero_p(self);' + end +end diff --git a/numeric.c b/numeric.c index 990d792..76567f8 100644 --- a/numeric.c +++ b/numeric.c @@ -39,6 +39,7 @@ https://github.com/ruby/ruby/blob/trunk/numeric.c#L39 #include "internal/variable.h" #include "ruby/encoding.h" #include "ruby/util.h" +#include "builtin.h" /* use IEEE 64bit values if not defined */ #ifndef FLT_RADIX @@ -769,20 +770,27 @@ num_abs(VALUE num) https://github.com/ruby/ruby/blob/trunk/numeric.c#L770 static VALUE num_zero_p(VALUE num) { + if (rb_equal(num, INT2FIX(0))) { + return Qtrue; + } + return Qfalse; +} + +static VALUE +int_zero_p(VALUE num) +{ if (FIXNUM_P(num)) { if (FIXNUM_ZERO_P(num)) { return Qtrue; } } - else if (RB_TYPE_P(num, T_BIGNUM)) { + else { + assert(RB_TYPE_P(num, T_BIGNUM)); if (rb_bigzero_p(num)) { /* this should not happen usually */ return Qtrue; } } - else if (rb_equal(num, INT2FIX(0))) { - return Qtrue; - } return Qfalse; } @@ -3307,7 +3315,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/numeric.c#L3315 int_anybits_p(VALUE num, VALUE mask) { mask = rb_to_int(mask); - return num_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue; + return int_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue; } /* @@ -3321,7 +3329,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/numeric.c#L3329 int_nobits_p(VALUE num, VALUE mask) { mask = rb_to_int(mask); - return num_zero_p(rb_int_and(num, mask)); + return int_zero_p(rb_int_and(num, mask)); } /* @@ -4722,7 +4730,7 @@ int_aref1(VALUE num, VALUE arg) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4730 if (!RTEST(num_negative_p(end))) { if (!excl) end = rb_int_plus(end, INT2FIX(1)); VALUE mask = generate_mask(end); - if (RTEST(num_zero_p(rb_int_and(num, mask)))) { + if (RTEST(int_zero_p(rb_int_and(num, mask)))) { return INT2FIX(0); } else { @@ -5844,3 +5852,5 @@ rb_float_new(double d) https://github.com/ruby/ruby/blob/trunk/numeric.c#L5852 { return rb_float_new_inline(d); } + +#include "integer.rbinc" diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb index 97c287f..0a70893 100644 --- a/test/ruby/test_jit.rb +++ b/test/ruby/test_jit.rb @@ -980,7 +980,7 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L980 def test_frame_omitted_inlining assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\ntrue\n", success_count: 1, min_calls: 2) begin; - class Numeric + class Integer remove_method :zero? def zero? self == 0 -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/