diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-09-01 12:02:36 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-09-01 12:02:36 +0000 |
commit | 2c8e7a50c1db8fea3fb012052828ad1eea51883f (patch) | |
tree | 9948c4ef01b8662c9d14a96cc228d7844af68b71 /include | |
parent | 0c5e6ab2bb6726b0d70e99db25d5369e196d8ddc (diff) | |
download | ruby-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.h | 1 | ||||
-rw-r--r-- | include/ruby/ruby.h | 34 |
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)) |