зеркало из https://github.com/github/ruby.git
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].
This commit is contained in:
Родитель
b68ddcf30c
Коммит
95b0fed371
|
@ -14,6 +14,7 @@ array.rb
|
|||
ast.rb
|
||||
dir.rb
|
||||
gc.rb
|
||||
integer.rb
|
||||
io.rb
|
||||
kernel.rb
|
||||
pack.rb
|
||||
|
|
2
NEWS.md
2
NEWS.md
|
@ -214,6 +214,8 @@ Excluding feature bug fixes.
|
|||
|
||||
* 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.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
benchmark:
|
||||
- 0.zero?
|
||||
- 1.zero?
|
||||
- 0r.zero?
|
||||
- 1r.zero?
|
||||
- 0i.zero?
|
||||
- 1i.zero?
|
||||
loop_count: 50000000
|
|
@ -1008,6 +1008,7 @@ $(srcs_vpath)mjit_compile.inc: $(tooldir)/ruby_vm/views/mjit_compile.inc.erb $(i
|
|||
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
|
|||
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
|
|||
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
|
||||
|
|
1
inits.c
1
inits.c
|
@ -82,6 +82,7 @@ rb_call_builtin_inits(void)
|
|||
{
|
||||
#define BUILTIN(n) CALL(builtin_##n)
|
||||
BUILTIN(gc);
|
||||
BUILTIN(integer);
|
||||
BUILTIN(io);
|
||||
BUILTIN(dir);
|
||||
BUILTIN(ast);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
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
|
24
numeric.c
24
numeric.c
|
@ -39,6 +39,7 @@
|
|||
#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
|
||||
|
@ -768,21 +769,28 @@ num_abs(VALUE num)
|
|||
|
||||
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
|
|||
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
|
|||
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)
|
|||
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)
|
|||
{
|
||||
return rb_float_new_inline(d);
|
||||
}
|
||||
|
||||
#include "integer.rbinc"
|
||||
|
|
|
@ -980,7 +980,7 @@ class TestJIT < Test::Unit::TestCase
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче