diff --git a/ChangeLog b/ChangeLog index 298e4b94b5..cd13554066 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,9 +8,9 @@ Wed Apr 9 14:05:00 2003 Nobuyoshi Nakada * marshal.c (w_object): preserve extended module on struct. (ruby-bugs-ja:PR#422) -Tue Apr 8 17:13:53 2003 Yukihiro Matsumoto +Wed Apr 9 03:43:14 2003 Yukihiro Matsumoto - * random.c (rb_f_rand): normalize bignum argument. + * bignum.c (BIGZEROP): macro to determine if x is a bignum zero. Tue Apr 8 11:49:31 2003 Yukihiro Matsumoto diff --git a/bignum.c b/bignum.c index 577f072ee3..0ae88ab713 100644 --- a/bignum.c +++ b/bignum.c @@ -33,6 +33,8 @@ VALUE rb_cBignum; #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1))) #define BDIGMAX ((BDIGIT)-1) +#define BIGZEROP(x) (RBIGNUM(x)->len == 0 || (RBIGNUM(x)->len == 1 && BDIGITS(x)[0] == 0)) + static VALUE bignew_1(klass, len, sign) VALUE klass; @@ -612,7 +614,7 @@ rb_big2str(x, base) return rb_fix2str(x, base); } i = RBIGNUM(x)->len; - if (i == 0 || (i == 1 && BDIGITS(x)[0] == 0)) { + if (BIGZEROP(x)) { return rb_str_new2("0"); } if (base == 10) { @@ -1123,8 +1125,8 @@ bigdivrem(x, y, divp, modp) BDIGIT_DBL_SIGNED num; BDIGIT dd, q; + if (BIGZEROP(y)) rb_num_zerodiv(); yds = BDIGITS(y); - if (ny == 0 && yds[0] == 0) rb_num_zerodiv(); if (nx < ny || (nx == ny && BDIGITS(x)[nx - 1] < BDIGITS(y)[ny - 1])) { if (divp) *divp = rb_int2big(0); if (modp) *modp = x; @@ -1248,8 +1250,7 @@ bigdivmod(x, y, divp, modp) VALUE mod; bigdivrem(x, y, divp, &mod); - if (RBIGNUM(x)->sign != RBIGNUM(y)->sign && - !(RBIGNUM(mod)->len == 1 && BDIGITS(mod)[0] == 0)) { + if (RBIGNUM(x)->sign != RBIGNUM(y)->sign && !BIGZEROP(x)) { if (divp) *divp = bigadd(*divp, rb_int2big(1), 0); if (modp) *modp = bigadd(mod, y, 1); } @@ -1728,8 +1729,8 @@ rb_big_rand(max, rand_buf) { VALUE v; long len = RBIGNUM(max)->len; - - if (len == 0 && BDIGITS(max)[0] == 0) { + + if (BIGZEROP(max)) { return rb_float_new(rand_buf[0]); } v = bignew(len,1); diff --git a/eval.c b/eval.c index 5ffcdb04c8..c2fdd158dd 100644 --- a/eval.c +++ b/eval.c @@ -5083,7 +5083,7 @@ backtrace(lev) { struct FRAME *frame = ruby_frame; char buf[BUFSIZ]; - VALUE ary; + volatile VALUE ary; NODE *n; ary = rb_ary_new(); diff --git a/gc.c b/gc.c index 6c8e9f650e..57e1ebac8f 100644 --- a/gc.c +++ b/gc.c @@ -381,9 +381,11 @@ static unsigned int STACK_LEVEL_MAX = 655300; : STACK_END - rb_gc_stack_start) #endif +#define GC_WARTER_MARK 512 + #define CHECK_STACK(ret) do {\ SET_STACK_END;\ - (ret) = (STACK_LENGTH > STACK_LEVEL_MAX);\ + (ret) = (STACK_LENGTH > STACK_LEVEL_MAX + GC_WARTER_MARK);\ } while (0) int @@ -460,25 +462,6 @@ sweep_source_filename(key, value) } } -static void -gc_mark_all() -{ - RVALUE *p, *pend; - int i; - - init_mark_stack(); - for (i = 0; i < heaps_used; i++) { - p = heaps[i]; pend = p + heaps_limits[i]; - while (p < pend) { - if ((p->as.basic.flags & FL_MARK) && - (p->as.basic.flags != FL_MARK)) { - rb_gc_mark((VALUE)p); - } - p++; - } - } -} - static void gc_mark_rest() { @@ -491,10 +474,32 @@ gc_mark_rest() init_mark_stack(); while(p != tmp_arry){ p--; + FL_UNSET(*p, FL_MARK); rb_gc_mark(*p); } } +static void +gc_mark_all() +{ + RVALUE *p, *pend; + int i; + + gc_mark_rest(); + init_mark_stack(); + for (i = 0; i < heaps_used; i++) { + p = heaps[i]; pend = p + heaps_limits[i]; + while (p < pend) { + if ((p->as.basic.flags & FL_MARK) && + (p->as.basic.flags != FL_MARK)) { + FL_UNSET(p, FL_MARK); + rb_gc_mark((VALUE)p); + } + p++; + } + } +} + static inline int is_pointer_to_heap(ptr) void *ptr; @@ -597,6 +602,11 @@ rb_gc_mark(ptr) CHECK_STACK(ret); if (ret) { + obj = RANY(ptr); + if (rb_special_const_p(ptr)) return; /* special const not marked */ + if (obj->as.basic.flags == 0) return; /* free cell */ + if (obj->as.basic.flags & FL_MARK) return; /* already marked */ + obj->as.basic.flags |= FL_MARK; if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr; diff --git a/random.c b/random.c index b04bcddb8f..86c8198d41 100644 --- a/random.c +++ b/random.c @@ -215,11 +215,6 @@ rb_f_rand(argc, argv, obj) vmax = rb_dbl2big(RFLOAT(vmax)->value); /* fall through */ case T_BIGNUM: - vmax = rb_big_norm(vmax); - if (FIXNUM_P(vmax)) { - max = FIX2INT(vmax); - break; - } bignum: { long len = RBIGNUM(vmax)->len;