Feature #3322 » cow.patch
| gc.c (working copy) | ||
|---|---|---|
|
void *membase;
|
||
|
RVALUE *slot;
|
||
|
size_t limit;
|
||
|
int leaked;
|
||
|
};
|
||
|
#define HEAP_MIN_SLOTS 10000
|
||
| ... | ... | |
|
/*
|
||
|
* call-seq:
|
||
|
* GC.leak -> nil
|
||
|
*
|
||
|
* marks all heaps as leaked and all objects with FL_MARK
|
||
|
* to prevent GC from touching that memory (COW-friendly)
|
||
|
*/
|
||
|
static VALUE
|
||
|
gc_leak(VALUE self)
|
||
|
{
|
||
|
rb_objspace_t *objspace = &rb_objspace;
|
||
|
RVALUE *p, *pend;
|
||
|
size_t i;
|
||
|
for (i = 0; i < heaps_used; i++) {
|
||
|
p = heaps[i].slot; pend = p + heaps[i].limit;
|
||
|
while (p < pend) {
|
||
|
if ((p->as.basic.flags != 0) &&
|
||
|
!(p->as.basic.flags & FL_MARK)) {
|
||
|
p->as.basic.flags |= FL_MARK;
|
||
|
}
|
||
|
p++;
|
||
|
}
|
||
|
heaps[i].leaked = TRUE;
|
||
|
}
|
||
|
freelist = NULL;
|
||
|
return Qnil;
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* GC.unleak -> nil
|
||
|
*
|
||
|
* set currently leaked heaps to be reclaimed on next GC
|
||
|
*/
|
||
|
static VALUE
|
||
|
gc_unleak(VALUE self)
|
||
|
{
|
||
|
rb_objspace_t *objspace = &rb_objspace;
|
||
|
size_t i;
|
||
|
for (i = 0; i < heaps_used; i++) {
|
||
|
heaps[i].leaked = FALSE;
|
||
|
}
|
||
|
return Qnil;
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* GC.stress -> true or false
|
||
|
*
|
||
|
* returns current status of GC stress mode.
|
||
| ... | ... | |
|
heaps[hi].membase = membase;
|
||
|
heaps[hi].slot = p;
|
||
|
heaps[hi].limit = objs;
|
||
|
heaps[hi].leaked = FALSE;
|
||
|
pend = p + objs;
|
||
|
if (lomem == 0 || lomem > p) lomem = p;
|
||
|
if (himem < pend) himem = pend;
|
||
| ... | ... | |
|
RVALUE *final = final_list;
|
||
|
int deferred;
|
||
|
if (heaps[i].leaked) continue;
|
||
|
p = heaps[i].slot; pend = p + heaps[i].limit;
|
||
|
while (p < pend) {
|
||
|
if (!(p->as.basic.flags & FL_MARK)) {
|
||
| ... | ... | |
|
rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0);
|
||
|
rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
|
||
|
rb_define_singleton_method(rb_mGC, "disable", rb_gc_disable, 0);
|
||
|
rb_define_singleton_method(rb_mGC, "leak", gc_leak, 0);
|
||
|
rb_define_singleton_method(rb_mGC, "unleak", gc_unleak, 0);
|
||
|
rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0);
|
||
|
rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1);
|
||
|
rb_define_singleton_method(rb_mGC, "count", gc_count, 0);
|
||