Backported GC.stress for 1.8

e$B:XF#$H?=$7$^$9!#e(B

GC.stresse$B$re(B1.8e$B%V%i%s%A$K9g$&$h$&!“%Q%C%A$r:n$j$^$7$?!#e(B
1.8e$B7ONs$N3+H/$K$bM-MQ$G$”$k$N$OJQ$o$j$J$$$H;W$&$N$G!"e(B1.8.7e$B$K8~$1$FDI2C$re(B
e$B9M$($F$$$?$@$1$k$H$&$l$7$$$G$9!#e(B

Index: signal.c

— signal.c (revision 15162)
+++ signal.c (working copy)
@@ -622,6 +622,8 @@
}
#endif

  • extern int ruby_gc_stress;
  • ruby_gc_stress = 0;
    rb_bug(“Segmentation fault”);
    }
    #endif
    Index: gc.c
    ===================================================================
    — gc.c (revision 15162)
    +++ gc.c (working copy)
    @@ -87,6 +87,39 @@
    rb_exc_raise(nomem_error);
    }

+/*

    • call-seq:
    • GC.stress => true or false
    • returns current status of GC stress mode.
  • */

+static VALUE
+gc_stress_get(VALUE self)
+{

  • return ruby_gc_stress ? Qtrue : Qfalse;
    +}

+/*

    • call-seq:
    • GC.stress = bool => bool
    • updates GC stress mode.
    • When GC.stress = true, GC is invoked for all GC opportunity:
    • all memory and object allocation.
    • Since it makes Ruby very slow, it is only for debugging.
  • */

+static VALUE
+gc_stress_set(VALUE self, VALUE bool)
+{

  • rb_secure(2);
  • ruby_gc_stress = RTEST(bool);
  • return bool;
    +}

void *
ruby_xmalloc(size)
long size;
@@ -99,7 +132,7 @@
if (size == 0) size = 1;
malloc_increase += size;

  • if (malloc_increase > malloc_limit) {
  • if (ruby_gc_stress || malloc_increase > malloc_limit) {
    garbage_collect();
    }
    RUBY_CRITICAL(mem = malloc(size));
    @@ -139,6 +172,7 @@
    if (!ptr) return xmalloc(size);
    if (size == 0) size = 1;
    malloc_increase += size;
  • if (ruby_gc_stress) garbage_collect();
    RUBY_CRITICAL(mem = realloc(ptr, size));
    if (!mem) {
    garbage_collect();
    @@ -378,7 +412,7 @@
    {
    VALUE obj;
  • if (!freelist) garbage_collect();
  • if (ruby_gc_stress || !freelist) garbage_collect();

    obj = (VALUE)freelist;
    freelist = freelist->as.free.next;
    @@ -413,6 +447,8 @@
    VALUE *rb_gc_register_stack_start = 0;
    #endif

+int ruby_gc_stress = 0;
+
#ifdef DJGPP
/* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) /
unsigned int _stklen = 0x180000; /
1.5 kB */
@@ -2032,6 +2068,8 @@
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, “stress”, gc_stress_get, 0);

  • rb_define_singleton_method(rb_mGC, “stress=”, gc_stress_set, 1);
    rb_define_method(rb_mGC, “garbage_collect”, rb_gc_start, 0);

    rb_mObSpace = rb_define_module(“ObjectSpace”);

e$B:XF#$G$9!#e(B

On Tue, 22 Jan 2008 04:12:12 +0900
Tadashi S. [email protected] wrote:

GC.stresse$B$re(B1.8e$B%V%i%s%A$K9g$&$h$&!"%Q%C%A$r:n$j$^$7$?!#e(B

e$B$9$$^$;$s!"@hDx$N$b$N$K$OK^%%9$,$"$j$^$7$?!#L5;k$7$F2<$5$$!#e(B

Index: signal.c

— signal.c (revision 15162)
+++ signal.c (working copy)
@@ -622,6 +622,8 @@
}
#endif

  • extern int ruby_gc_stress;
  • ruby_gc_stress = 0;
    rb_bug(“Segmentation fault”);
    }
    #endif
    Index: gc.c
    ===================================================================
    — gc.c (revision 15162)
    +++ gc.c (working copy)
    @@ -74,6 +74,8 @@
    static VALUE nomem_error;
    static void garbage_collect();

+int ruby_gc_stress = 0;
+
void
rb_memerror()
{
@@ -87,6 +89,39 @@
rb_exc_raise(nomem_error);
}

+/*

    • call-seq:
    • GC.stress => true or false
    • returns current status of GC stress mode.
  • */

+static VALUE
+gc_stress_get(VALUE self)
+{

  • return ruby_gc_stress ? Qtrue : Qfalse;
    +}

+/*

    • call-seq:
    • GC.stress = bool => bool
    • updates GC stress mode.
    • When GC.stress = true, GC is invoked for all GC opportunity:
    • all memory and object allocation.
    • Since it makes Ruby very slow, it is only for debugging.
  • */

+static VALUE
+gc_stress_set(VALUE self, VALUE bool)
+{

  • rb_secure(2);
  • ruby_gc_stress = RTEST(bool);
  • return bool;
    +}

void *
ruby_xmalloc(size)
long size;
@@ -99,7 +134,7 @@
if (size == 0) size = 1;
malloc_increase += size;

  • if (malloc_increase > malloc_limit) {
  • if (ruby_gc_stress || malloc_increase > malloc_limit) {
    garbage_collect();
    }
    RUBY_CRITICAL(mem = malloc(size));
    @@ -139,6 +174,7 @@
    if (!ptr) return xmalloc(size);
    if (size == 0) size = 1;
    malloc_increase += size;
  • if (ruby_gc_stress) garbage_collect();
    RUBY_CRITICAL(mem = realloc(ptr, size));
    if (!mem) {
    garbage_collect();
    @@ -378,7 +414,7 @@
    {
    VALUE obj;
  • if (!freelist) garbage_collect();
  • if (ruby_gc_stress || !freelist) garbage_collect();

    obj = (VALUE)freelist;
    freelist = freelist->as.free.next;
    @@ -2032,6 +2068,8 @@
    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, “stress”, gc_stress_get, 0);

  • rb_define_singleton_method(rb_mGC, “stress=”, gc_stress_set, 1);
    rb_define_method(rb_mGC, “garbage_collect”, rb_gc_start, 0);

    rb_mObSpace = rb_define_module(“ObjectSpace”);