From b54786ffbce89d8bd3320eeed0eb385c647c744d Mon Sep 17 00:00:00 2001 From: kazu Date: Tue, 15 Apr 2008 07:54:11 +0000 Subject: * signal.c, gc.c: New methods: GC.stress, GC.stress=; backported from 1.9. a patch from Tadashi Saito in [ruby-dev:34394] and bug#19000 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@16030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ NEWS | 5 +++++ gc.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- signal.c | 2 ++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8cf802021..264030ea64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Apr 15 16:47:48 2008 Kazuhiro NISHIYAMA + + * signal.c, gc.c: New methods: GC.stress, GC.stress=; + backported from 1.9. a patch from Tadashi Saito + in [ruby-dev:34394] and bug#19000 + Tue Apr 15 12:35:44 2008 Nobuyoshi Nakada * rubyio.h (rb_io_t): renamed from OpenFile. diff --git a/NEWS b/NEWS index 68266322f6..0f921ad415 100644 --- a/NEWS +++ b/NEWS @@ -139,6 +139,11 @@ with all sufficient information, see the ChangeLog file. Return an enumerator if no block is given. + * GC.stress + * GC.stress= + + New methods. + * Integer#ord * Integer#odd? * Integer#even? diff --git a/gc.c b/gc.c index 5802f0a945..daf3bcd51f 100644 --- a/gc.c +++ b/gc.c @@ -76,6 +76,8 @@ static void run_final(); static VALUE nomem_error; static void garbage_collect(); +int ruby_gc_stress = 0; + void rb_memerror() { @@ -89,6 +91,41 @@ rb_memerror() rb_exc_raise(nomem_error); } +/* + * call-seq: + * GC.stress => true or false + * + * returns current status of GC stress mode. + */ + +static VALUE +gc_stress_get(self) + 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(self, bool) + VALUE self, bool; +{ + rb_secure(2); + ruby_gc_stress = RTEST(bool); + return bool; +} + void * ruby_xmalloc(size) long size; @@ -101,7 +138,7 @@ ruby_xmalloc(size) 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)); @@ -141,6 +178,7 @@ ruby_xrealloc(ptr, size) 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(); @@ -383,7 +421,7 @@ rb_newobj() if (during_gc) rb_bug("object allocation during garbage collection phase"); - if (!freelist) garbage_collect(); + if (ruby_gc_stress || !freelist) garbage_collect(); obj = (VALUE)freelist; freelist = freelist->as.free.next; @@ -2037,6 +2075,8 @@ Init_GC() 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"); diff --git a/signal.c b/signal.c index 401dd90d5b..81fb280a09 100644 --- a/signal.c +++ b/signal.c @@ -628,6 +628,8 @@ sigsegv(sig) } #endif + extern int ruby_gc_stress; + ruby_gc_stress = 0; rb_bug("Segmentation fault"); } #endif -- cgit v1.2.3