ruby-changes:17538
From: nari <ko1@a...>
Date: Thu, 21 Oct 2010 13:18:19 +0900 (JST)
Subject: [ruby-changes:17538] Ruby:r29543 (trunk): * gc.c (rb_objspace_each_objects): don't lazy sweep in
nari 2010-10-21 13:18:09 +0900 (Thu, 21 Oct 2010) New Revision: 29543 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29543 Log: * gc.c (rb_objspace_each_objects): don't lazy sweep in rb_objspace_each_objects. [Bug #3940] [ruby-dev:42369] Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 29542) +++ ChangeLog (revision 29543) @@ -1,3 +1,8 @@ +Thu Oct 21 13:08:00 2010 Narihiro Nakamura <authornari@g...> + + * 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@r...> * test/ruby/test_io.rb (TestIO#pipe): get rid of deadlock on pipe. Index: gc.c =================================================================== --- gc.c (revision 29542) +++ gc.c (revision 29543) @@ -332,6 +332,7 @@ } heap; struct { int dont_gc; + int dont_lazy_sweep; int during_gc; } flags; struct { @@ -2040,6 +2041,17 @@ 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 @@ { 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(&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 @@ 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; + rest_sweep(objspace); + objspace->flags.dont_lazy_sweep = TRUE; - 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; - } - } - } - - return; + args[0] = (VALUE)callback; + args[1] = (VALUE)data; + rb_ensure(objspace_each_objects, (VALUE)args, lazy_sweep_enable, Qnil); } struct os_each_struct { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/