aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-09-01 12:02:36 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-09-01 12:02:36 +0000
commit2c8e7a50c1db8fea3fb012052828ad1eea51883f (patch)
tree9948c4ef01b8662c9d14a96cc228d7844af68b71 /include
parent0c5e6ab2bb6726b0d70e99db25d5369e196d8ddc (diff)
downloadruby-2c8e7a50c1db8fea3fb012052828ad1eea51883f.tar.gz
* include/ruby/ruby.h (struct RBignum): embed digits in RBignum for
small bignums. * bignum.c: RBignum embeded digits implemented. * include/ruby/intern.h: declare rb_big_resize. * gc.c: don't free embedded digits. * numeric.c: replace direct bignum field accessor by abstract field accessor such as RBIGNUM(val)->sign to RBIGNUM_SIGN(val). * sprintf.c: ditto. * compar.c: ditto. * marshal.c: ditto. * random.c: ditto. * .gdbinit: support embedded small bignums. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13330 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'include')
-rw-r--r--include/ruby/intern.h1
-rw-r--r--include/ruby/ruby.h34
2 files changed, 32 insertions, 3 deletions
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 829d732893..e3776b8c6b 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -77,6 +77,7 @@ VALUE rb_get_values_at(VALUE, long, int, VALUE*, VALUE(*)(VALUE,long));
VALUE rb_big_clone(VALUE);
void rb_big_2comp(VALUE);
VALUE rb_big_norm(VALUE);
+void rb_big_resize(VALUE big, long len);
VALUE rb_uint2big(VALUE);
VALUE rb_int2big(SIGNED_VALUE);
VALUE rb_uint2inum(VALUE);
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index bf5804f647..5ccf246734 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -547,12 +547,38 @@ struct RStruct {
RSTRUCT(st)->as.ary : \
RSTRUCT(st)->as.heap.ptr)
+#define RBIGNUM_EMBED_LEN_MAX ((sizeof(VALUE)*3)/sizeof(BDIGIT))
struct RBignum {
struct RBasic basic;
- char sign; /* positive:1, negative:0 */
- long len;
- void *digits;
+ union {
+ struct {
+ long len;
+ BDIGIT *digits;
+ } heap;
+ BDIGIT ary[RBIGNUM_EMBED_LEN_MAX];
+ } as;
};
+#define RBIGNUM_SIGN_BIT FL_USER1
+/* sign: positive:1, negative:0 */
+#define RBIGNUM_SIGN(b) ((RBASIC(b)->flags & RBIGNUM_SIGN_BIT) != 0)
+#define RBIGNUM_SET_SIGN(b,sign) \
+ ((sign) ? (RBASIC(b)->flags |= RBIGNUM_SIGN_BIT) \
+ : (RBASIC(b)->flags &= ~RBIGNUM_SIGN_BIT))
+#define RBIGNUM_POSITIVE_P(b) RBIGNUM_SIGN(b)
+#define RBIGNUM_NEGATIVE_P(b) (!RBIGNUM_SIGN(b))
+
+#define RBIGNUM_EMBED_FLAG FL_USER2
+#define RBIGNUM_EMBED_LEN_MASK (FL_USER5|FL_USER4|FL_USER3)
+#define RBIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+3)
+#define RBIGNUM_LEN(b) \
+ ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
+ (long)((RBASIC(b)->flags >> RBIGNUM_EMBED_LEN_SHIFT) & \
+ (RBIGNUM_EMBED_LEN_MASK >> RBIGNUM_EMBED_LEN_SHIFT)) : \
+ RBIGNUM(b)->as.heap.len)
+#define RBIGNUM_DIGITS(b) \
+ ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
+ RBIGNUM(b)->as.ary : \
+ RBIGNUM(b)->as.heap.digits)
#define R_CAST(st) (struct st*)
#define RBASIC(obj) (R_CAST(RBasic)(obj))
@@ -631,6 +657,8 @@ enum ruby_value_flags {
#define FL_USER19 RUBY_FL_USER19
RUBY_FL_USER20 = (1<<(FL_USHIFT+20)),
#define FL_USER20 RUBY_FL_USER20
+ RUBY_FL_DUMMY = ~(VALUE)0 >> 1 /* make sizeof(enum ruby_value_flags)
+ equal to sizeof(VALUE). */
};
#define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x))