From: Tadashi Saito Date: 2008-01-22T04:12:12+09:00 Subject: [ruby-dev:33265] backported GC.stress for 1.8 斎藤と申します。 GC.stressを1.8ブランチに合うよう、パッチを作りました。 1.8系列の開発にも有用であるのは変わりないと思うので、1.8.7に向けて追加を 考えていただけるとうれしいです。 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"); -- 斎藤ただし