* gc.c (rb_objspace_each_objects): don't lazy sweep in
rb_objspace_each_objects. [Bug #3940] [ruby-dev:42369] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29543 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4c962daa2d
commit
a29dc56764
@ -1,3 +1,8 @@
|
|||||||
|
Thu Oct 21 13:08:00 2010 Narihiro Nakamura <authornari@gmail.com>
|
||||||
|
|
||||||
|
* gc.c (rb_objspace_each_objects): don't lazy sweep in
|
||||||
|
rb_objspace_each_objects. [Bug #3940] [ruby-dev:42369]
|
||||||
|
|
||||||
Thu Oct 21 00:05:45 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Oct 21 00:05:45 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* test/ruby/test_io.rb (TestIO#pipe): get rid of deadlock on pipe.
|
* test/ruby/test_io.rb (TestIO#pipe): get rid of deadlock on pipe.
|
||||||
|
100
gc.c
100
gc.c
@ -332,6 +332,7 @@ typedef struct rb_objspace {
|
|||||||
} heap;
|
} heap;
|
||||||
struct {
|
struct {
|
||||||
int dont_gc;
|
int dont_gc;
|
||||||
|
int dont_lazy_sweep;
|
||||||
int during_gc;
|
int during_gc;
|
||||||
} flags;
|
} flags;
|
||||||
struct {
|
struct {
|
||||||
@ -2040,6 +2041,17 @@ lazy_sweep(rb_objspace_t *objspace)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rest_sweep(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->heap.sweep_slots) {
|
||||||
|
while (objspace->heap.sweep_slots) {
|
||||||
|
lazy_sweep(objspace);
|
||||||
|
}
|
||||||
|
after_gc_sweep(objspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void gc_marks(rb_objspace_t *objspace);
|
static void gc_marks(rb_objspace_t *objspace);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2047,6 +2059,9 @@ gc_lazy_sweep(rb_objspace_t *objspace)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
if (objspace->flags.dont_lazy_sweep)
|
||||||
|
return garbage_collect(objspace);
|
||||||
|
|
||||||
INIT_GC_PROF_PARAMS;
|
INIT_GC_PROF_PARAMS;
|
||||||
|
|
||||||
if (!ready_to_gc(objspace)) return TRUE;
|
if (!ready_to_gc(objspace)) return TRUE;
|
||||||
@ -2489,6 +2504,55 @@ Init_heap(void)
|
|||||||
init_heap(&rb_objspace);
|
init_heap(&rb_objspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
lazy_sweep_enable(void)
|
||||||
|
{
|
||||||
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
|
|
||||||
|
objspace->flags.dont_lazy_sweep = FALSE;
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
objspace_each_objects(VALUE arg)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
RVALUE *membase = 0;
|
||||||
|
RVALUE *pstart, *pend;
|
||||||
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
|
VALUE *args = (VALUE *)arg;
|
||||||
|
volatile VALUE v;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < heaps_used) {
|
||||||
|
while (0 < i && (uintptr_t)membase < (uintptr_t)objspace->heap.sorted[i-1].slot->membase)
|
||||||
|
i--;
|
||||||
|
while (i < heaps_used && (uintptr_t)objspace->heap.sorted[i].slot->membase <= (uintptr_t)membase )
|
||||||
|
i++;
|
||||||
|
if (heaps_used <= i)
|
||||||
|
break;
|
||||||
|
membase = objspace->heap.sorted[i].slot->membase;
|
||||||
|
|
||||||
|
pstart = objspace->heap.sorted[i].slot->slot;
|
||||||
|
pend = pstart + objspace->heap.sorted[i].slot->limit;
|
||||||
|
|
||||||
|
for (; pstart != pend; pstart++) {
|
||||||
|
if (pstart->as.basic.flags) {
|
||||||
|
v = (VALUE)pstart; /* acquire to save this object */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pstart != pend) {
|
||||||
|
if ((*(int (*)(void *, void *, size_t, void *))args[0])(pstart, pend, sizeof(RVALUE), (void *)args[1])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rb_objspace_each_objects() is special C API to walk through
|
* rb_objspace_each_objects() is special C API to walk through
|
||||||
* Ruby object space. This C API is too difficult to use it.
|
* Ruby object space. This C API is too difficult to use it.
|
||||||
@ -2530,39 +2594,15 @@ rb_objspace_each_objects(int (*callback)(void *vstart, void *vend,
|
|||||||
size_t stride, void *d),
|
size_t stride, void *d),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
size_t i;
|
VALUE args[2];
|
||||||
RVALUE *membase = 0;
|
|
||||||
RVALUE *pstart, *pend;
|
|
||||||
rb_objspace_t *objspace = &rb_objspace;
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
volatile VALUE v;
|
|
||||||
|
|
||||||
i = 0;
|
rest_sweep(objspace);
|
||||||
while (i < heaps_used) {
|
objspace->flags.dont_lazy_sweep = TRUE;
|
||||||
while (0 < i && (uintptr_t)membase < (uintptr_t)objspace->heap.sorted[i-1].slot->membase)
|
|
||||||
i--;
|
|
||||||
while (i < heaps_used && (uintptr_t)objspace->heap.sorted[i].slot->membase <= (uintptr_t)membase )
|
|
||||||
i++;
|
|
||||||
if (heaps_used <= i)
|
|
||||||
break;
|
|
||||||
membase = objspace->heap.sorted[i].slot->membase;
|
|
||||||
|
|
||||||
pstart = objspace->heap.sorted[i].slot->slot;
|
args[0] = (VALUE)callback;
|
||||||
pend = pstart + objspace->heap.sorted[i].slot->limit;
|
args[1] = (VALUE)data;
|
||||||
|
rb_ensure(objspace_each_objects, (VALUE)args, lazy_sweep_enable, Qnil);
|
||||||
for (; pstart != pend; pstart++) {
|
|
||||||
if (pstart->as.basic.flags) {
|
|
||||||
v = (VALUE)pstart; /* acquire to save this object */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pstart != pend) {
|
|
||||||
if ((*callback)(pstart, pend, sizeof(RVALUE), data)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct os_each_struct {
|
struct os_each_struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user