nari$B$G$9!#(B
$B!!$3$l$@$H!“Nc$($PNc30$,=P$?>l9g!”(Bdont_lazy_sweep $B$,(B TRUE
$B$N$^$^$K$J$C$F(B
$B$7$^$&$h$&$J5$$,$7$^$9!#(Bensure $B$G0O$^$J$$$H!#(B
$B$)$)!"$=$&$G$9$M!D!#$4;XE&$"$j$,$H$&$4$6$$$^$9!#(B
$B$=$N$h$&$J%Q%C%A$r:n$C$F$_$^$7$?!#K%a!<%k$N0lHV:G8e$KE=$jIU$1$F$*$-$^$9!#(B
sweep $B$H$$$&4X?t$G(B mark $B$^$G$7$A$c$&$N$O$$$$$G$7$g$&$+!#(B
$B$J$k$[$I!#(B
$B4X?tL>$K(Bgc_$B$H$$$&%W%l%U%#%/%9$,IU$$$F$$$k$N$G!"%^!<%/$7$F$b$$$$$N$+$J$H(B
$B$+!"$=$&$$$&8@$$Lu$r;W$$$D$$$?$N$G$9$,$d$C$Q$j%@%a$G$9$M!#(B
$B$"$^$j!“BP0F$O$J$$$N$G$9$,!”$J$s$H$J$/!"(Bgarbage_collect() $B$r(B $B:#$N(B
gc_lazy_sweep() $B$H$7$F!":#$N(B garbage_collect() $B$r!"(B
garbage_collect_eager() $B$_$?$$$K$7$F$7$^$&$N$O$I$&$@$m$&!"$H;W$$$^$7$?!#(B
garbage_collect_eager() $B$h$j$b(B garbage_collect_full()
$B$NJ}$,Fk@w$_(B
$B$,$"$k$N$+$J$H;W$$$^$7$?!#$3$A$i$NJ}$b2K$r8+$D$1$FD>$7$F$*$-$^$9!#(B
$B%Q%C%A(B:
diff --git a/gc.c b/gc.c
index b011f4a…ad49fd5 100644
— a/gc.c
+++ b/gc.c
@@ -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)
+{
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;
- args[0] = (VALUE)callback;
- args[1] = (VALUE)data;
- rb_ensure(objspace_each_objects, (VALUE)args, lazy_sweep_enable,
Qnil);
}
struct os_each_struct {