diff --git a/gc.c b/gc.c index 8b5c1a388a..0f489659e5 100644 --- a/gc.c +++ b/gc.c @@ -302,7 +302,7 @@ add_heap() if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; - heap_slots *= 1.5; + heap_slots *= 1.8; while (p < pend) { p->as.free.flags = 0; @@ -371,14 +371,15 @@ static VALUE *mark_stack; static int mark_stack_overflow = 0; #define PUSH_MARK(obj) do {\ - if (!mark_stack_overflow) {\ + if (mark_stack_overflow) {\ + FL_SET((obj),FL_MARK);\ + }\ + else {\ if (mark_stack - mark_stack_base >= MARK_STACK_SIZE) {\ mark_stack_overflow = 1;\ -printf("mark stack overflow\n");\ }\ else {\ if ( rb_special_const_p(obj) /* special const not marked */\ - || RBASIC(obj)->flags == 0 /* free cell */\ || FL_TEST((obj),FL_MARK)) /* already marked */ {\ }\ else {\ @@ -392,6 +393,45 @@ printf("mark stack overflow\n");\ #define MARK_EMPTY() (mark_stack == mark_stack_base) +#ifdef NO_REGION + +#define PUSH_MARK_REGION(a,b) do {\ + VALUE *tmp_beg_ptr = (a);\ + while (tmp_beg_ptr < (b)) {\ + PUSH_MARK(*tmp_beg_ptr);\ + tmp_beg_ptr++;\ + }\ +} while (0) + +#else + +#define MARK_REGION_STACK_SIZE 1024 +static VALUE *mark_region_stack_base[MARK_REGION_STACK_SIZE]; +static VALUE **mark_region_stack; + +#define PUSH_MARK_REGION(a,b) do {\ + if (mark_region_stack - mark_region_stack_base >= MARK_REGION_STACK_SIZE || (b) - (a) < 3) {\ + VALUE *tmp_beg_ptr = (a);\ + while (tmp_beg_ptr < (b)) {\ + PUSH_MARK(*tmp_beg_ptr);\ + tmp_beg_ptr++;\ + }\ + }\ + else {\ + *mark_region_stack++ = (a);\ + *mark_region_stack++ = (b);\ + }\ +} while (0) + +#define POP_MARK_REGION(a,b) do {\ + (b) = (*--mark_region_stack);\ + (a) = (*--mark_region_stack);\ +} while (0) + +#define MARK_REGION_EMPTY() (mark_region_stack == mark_region_stack_base) + +#endif + static void mark_locations_array(x, n) register VALUE *x; @@ -438,6 +478,23 @@ rb_mark_tbl(tbl) st_foreach(tbl, mark_entry, 0); } +static int +push_entry(key, value) + ID key; + VALUE value; +{ + PUSH_MARK(value); + return ST_CONTINUE; +} + +static void +push_mark_tbl(tbl) + st_table *tbl; +{ + if (!tbl) return; + st_foreach(tbl, push_entry, 0); +} + static int mark_hashentry(key, value) VALUE key; @@ -456,6 +513,24 @@ rb_mark_hash(tbl) st_foreach(tbl, mark_hashentry, 0); } +static int +push_hashentry(key, value) + VALUE key; + VALUE value; +{ + PUSH_MARK(key); + PUSH_MARK(value); + return ST_CONTINUE; +} + +static void +push_mark_hash(tbl) + st_table *tbl; +{ + if (!tbl) return; + st_foreach(tbl, push_hashentry, 0); +} + void rb_gc_mark_maybe(obj) VALUE obj; @@ -624,8 +699,8 @@ gc_mark_children(ptr) case T_CLASS: case T_MODULE: PUSH_MARK(obj->as.klass.super); - rb_mark_tbl(obj->as.klass.m_tbl); - rb_mark_tbl(obj->as.klass.iv_tbl); + push_mark_tbl(obj->as.klass.m_tbl); + push_mark_tbl(obj->as.klass.iv_tbl); break; case T_ARRAY: @@ -633,23 +708,18 @@ gc_mark_children(ptr) int i, len = obj->as.array.len; VALUE *ptr = obj->as.array.ptr; - for (i=0; i < len; i++) { - PUSH_MARK(*ptr); - ptr++; - } + PUSH_MARK_REGION(ptr,ptr+len); } break; case T_HASH: - rb_mark_hash(obj->as.hash.tbl); - PUSH_MARK(obj->as.hash.ifnone); - break; + push_mark_hash(obj->as.hash.tbl); + obj = RANY(obj->as.hash.ifnone); + goto Again; case T_STRING: - if (obj->as.string.orig) { - obj = RANY(obj->as.string.orig); - goto Again; - } + obj = RANY(obj->as.string.orig); + goto Again; break; case T_DATA: @@ -657,7 +727,7 @@ gc_mark_children(ptr) break; case T_OBJECT: - rb_mark_tbl(obj->as.object.iv_tbl); + push_mark_tbl(obj->as.object.iv_tbl); break; case T_FILE: @@ -678,17 +748,14 @@ gc_mark_children(ptr) PUSH_MARK(obj->as.varmap.val); obj = RANY(obj->as.varmap.next); goto Again; - break; case T_SCOPE: if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { int n = obj->as.scope.local_tbl[0]+1; VALUE *vars = &obj->as.scope.local_vars[-1]; - while (n--) { - PUSH_MARK(*vars); - vars++; - } + + PUSH_MARK_REGION(vars,vars+n); } break; @@ -697,10 +764,7 @@ gc_mark_children(ptr) int i, len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; - for (i=0; i < len; i++) { - PUSH_MARK(*ptr); - ptr++; - } + PUSH_MARK_REGION(ptr,ptr+len); } break; @@ -724,7 +788,7 @@ rb_gc_mark(ptr) { if (rb_special_const_p(ptr)) return; /* special const not marked */ if (RBASIC(ptr)->flags == 0) return; /* free cell */ - if (FL_TEST((ptr),FL_MARK)) return; /* already marked */ + if (RBASIC(ptr)->flags & FL_MARK) return; /* already marked */ gc_mark_children(ptr); } @@ -733,6 +797,20 @@ gc_mark() { while (!MARK_EMPTY()) { rb_gc_mark(POP_MARK()); +#ifndef NO_REGION + while (!MARK_REGION_EMPTY()) { + VALUE *p, *pend; + + POP_MARK_REGION(p, pend); + while (p < pend) { + rb_gc_mark(*p); + p++; + } + while (!MARK_EMPTY()) { + rb_gc_mark(POP_MARK()); + } + } +#endif } } @@ -1040,8 +1118,11 @@ rb_gc() if (during_gc) return; during_gc++; - mark_stack = mark_stack_base; mark_stack_overflow = 0; + mark_stack = mark_stack_base; +#ifndef NO_REGION + mark_region_stack = mark_region_stack_base; +#endif /* mark frame stack */ for (frame = ruby_frame; frame; frame = frame->prev) { rb_gc_mark_frame(frame); diff --git a/version.h b/version.h index 1429ae085f..446b65ead3 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ -#define RUBY_VERSION "1.7.1" -#define RUBY_RELEASE_DATE "2001-11-01" -#define RUBY_VERSION_CODE 171 -#define RUBY_RELEASE_CODE 20011101 +#define RUBY_VERSION "1.7.2" +#define RUBY_RELEASE_DATE "2001-11-02" +#define RUBY_VERSION_CODE 172 +#define RUBY_RELEASE_CODE 20011102