aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-03-06 11:14:05 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-03-06 11:14:05 +0000
commit42fe57d41b6a317d31f817f75e04851281e27750 (patch)
tree148c82adfc714aaa2a3d60cda2c18c4f78ed9f76 /include
parentc24d87191f249ef8fdd363226dce2fd67475079c (diff)
downloadruby-42fe57d41b6a317d31f817f75e04851281e27750.tar.gz
optimize FIXABLE macro
Looking at the source code, FIXABLE tends to be just before LOING2FIX to check applicability of that operation. Why not try computing first then check for overflow, which should be optimial. I also tried the same thing for unsigned types but resulted in slower execution. It seems RB_POSFIXABLE() is fast enough on modern CPUs. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'include')
-rw-r--r--include/ruby/ruby.h37
1 files changed, 31 insertions, 6 deletions
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index d770c30735..0cd88fb002 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1504,6 +1504,29 @@ rb_integer_type_p(VALUE obj)
}
#endif
+static inline int
+rb_long2fix_overflow(long l, VALUE *ptr)
+{
+#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
+ SIGNED_VALUE v;
+ if (__builtin_mul_overflow(l, 2, &v)) {
+ return 1;
+ }
+ else {
+ *ptr = ((VALUE)v) | RUBY_FIXNUM_FLAG;
+ return 0;
+ }
+#else
+ if (RB_FIXABLE(l)) {
+ *ptr = RB_LONG2FIX(l);
+ return 0;
+ }
+ else {
+ return 1;
+ }
+#endif
+}
+
#if SIZEOF_INT < SIZEOF_LONG
# define RB_INT2NUM(v) RB_INT2FIX((int)(v))
# define RB_UINT2NUM(v) RB_LONG2FIX((unsigned int)(v))
@@ -1511,10 +1534,11 @@ rb_integer_type_p(VALUE obj)
static inline VALUE
rb_int2num_inline(int v)
{
- if (RB_FIXABLE(v))
- return RB_INT2FIX(v);
- else
+ VALUE ret;
+ if (rb_long2fix_overflow(v, &ret))
return rb_int2big(v);
+ else
+ return ret;
}
#define RB_INT2NUM(x) rb_int2num_inline(x)
@@ -1534,10 +1558,11 @@ rb_uint2num_inline(unsigned int v)
static inline VALUE
rb_long2num_inline(long v)
{
- if (RB_FIXABLE(v))
- return RB_LONG2FIX(v);
- else
+ VALUE ret;
+ if (rb_long2fix_overflow(v, &ret))
return rb_int2big(v);
+ else
+ return ret;
}
#define RB_LONG2NUM(x) rb_long2num_inline(x)