diff options
author | nari <nari@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-10-21 04:18:09 +0000 |
---|---|---|
committer | nari <nari@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-10-21 04:18:09 +0000 |
commit | a29dc5676415163b0e2416a07de4a9d8055a4670 (patch) | |
tree | f9249c80c30c04748df2a70f45c362fdd97c8041 | |
parent | 4c962daa2d1679b9685e984fe04eef521007aa3e (diff) | |
download | ruby-a29dc5676415163b0e2416a07de4a9d8055a4670.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | gc.c | 100 |
2 files changed, 75 insertions, 30 deletions
@@ -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> * test/ruby/test_io.rb (TestIO#pipe): get rid of deadlock on pipe. @@ -332,6 +332,7 @@ typedef struct rb_objspace { } heap; struct { int dont_gc; + int dont_lazy_sweep; int during_gc; } flags; struct { @@ -2040,6 +2041,17 @@ lazy_sweep(rb_objspace_t *objspace) 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 int @@ -2047,6 +2059,9 @@ gc_lazy_sweep(rb_objspace_t *objspace) { int res; + if (objspace->flags.dont_lazy_sweep) + return garbage_collect(objspace); + INIT_GC_PROF_PARAMS; if (!ready_to_gc(objspace)) return TRUE; @@ -2489,6 +2504,55 @@ Init_heap(void) 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 * 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), void *data) { - size_t i; - RVALUE *membase = 0; - RVALUE *pstart, *pend; + VALUE args[2]; rb_objspace_t *objspace = &rb_objspace; - 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 ((*callback)(pstart, pend, sizeof(RVALUE), data)) { - return; - } - } - } + rest_sweep(objspace); + objspace->flags.dont_lazy_sweep = TRUE; - return; + args[0] = (VALUE)callback; + args[1] = (VALUE)data; + rb_ensure(objspace_each_objects, (VALUE)args, lazy_sweep_enable, Qnil); } struct os_each_struct { |