git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1811 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2001-11-02 07:20:58 +00:00
Родитель bbb608ad79
Коммит 7ef9fbb35f
2 изменённых файлов: 114 добавлений и 33 удалений

139
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);

Просмотреть файл

@ -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