summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--bignum.c13
-rw-r--r--eval.c2
-rw-r--r--gc.c44
-rw-r--r--random.c5
5 files changed, 37 insertions, 31 deletions
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 <nobu.nokada@softhome.net>
* marshal.c (w_object): preserve extended module on struct.
(ruby-bugs-ja:PR#422)
-Tue Apr 8 17:13:53 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+Wed Apr 9 03:43:14 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
- * 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 <matz@ruby-lang.org>
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
@@ -461,17 +463,36 @@ sweep_source_filename(key, value)
}
static void
+gc_mark_rest()
+{
+ VALUE tmp_arry[MARK_STACK_MAX];
+ VALUE *p;
+
+ p = (mark_stack_ptr - mark_stack) + tmp_arry;
+ MEMCPY(tmp_arry, mark_stack, VALUE, MARK_STACK_MAX);
+
+ 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++;
@@ -479,22 +500,6 @@ gc_mark_all()
}
}
-static void
-gc_mark_rest()
-{
- VALUE tmp_arry[MARK_STACK_MAX];
- VALUE *p;
-
- p = (mark_stack_ptr - mark_stack) + tmp_arry;
- MEMCPY(tmp_arry, mark_stack, VALUE, MARK_STACK_MAX);
-
- init_mark_stack();
- while(p != tmp_arry){
- p--;
- rb_gc_mark(*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;