Project

General

Profile

Feature #3322 » cow2.patch

Dan42 (Daniel DeLorme), 05/21/2010 08:55 AM

View differences:

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;
garbage_collect(objspace);
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;
}
garbage_collect(objspace);
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);
(2-2/2)