From c8c99520668f4a92f620ede01e5af2827a29b3fa Mon Sep 17 00:00:00 2001 From: ko1 Date: Tue, 10 Jun 2014 16:55:32 +0000 Subject: [PATCH] * gc.c: invoke GC before memory allocation (xmalloc/xrealloc) when GC.stress = true. [Bug #9859] * test/ruby/test_gc.rb: add a test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46399 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++++++ gc.c | 15 +++++++++------ test/ruby/test_gc.rb | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1311347709..8ee23d4610 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Wed Jun 11 01:53:22 2014 Koichi Sasada + + * gc.c: invoke GC before memory allocation (xmalloc/xrealloc) + when GC.stress = true. + [Bug #9859] + + * test/ruby/test_gc.rb: add a test. + Tue Jun 10 13:20:14 2014 Takeyuki FUJIOKA * lib/cgi/core.rb: Provide a mechanism to specify the diff --git a/gc.c b/gc.c index c807d5119a..ba70b33cc1 100644 --- a/gc.c +++ b/gc.c @@ -6230,6 +6230,14 @@ atomic_sub_nounderflow(size_t *var, size_t sub) } } +static void +objspace_malloc_gc_stress(rb_objspace_t *objspace) +{ + if (ruby_gc_stress && !ruby_disable_gc_stress && ruby_native_thread_p()) { + garbage_collect_with_gvl(objspace, gc_stress_full_mark_after_malloc_p(), TRUE, GPR_FLAG_STRESS | GPR_FLAG_MALLOC); + } +} + static void objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, size_t old_size, enum memop_type type) { @@ -6246,12 +6254,6 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si #endif } - if (type != MEMOP_TYPE_FREE && - ruby_gc_stress && !ruby_disable_gc_stress && - ruby_native_thread_p()) { - garbage_collect_with_gvl(objspace, gc_stress_full_mark_after_malloc_p(), TRUE, GPR_FLAG_MALLOC); - } - if (type == MEMOP_TYPE_MALLOC) { retry: if (malloc_increase > malloc_limit && ruby_native_thread_p()) { @@ -6335,6 +6337,7 @@ objspace_malloc_fixup(rb_objspace_t *objspace, void *mem, size_t size) } #define TRY_WITH_GC(alloc) do { \ + objspace_malloc_gc_stress(objspace); \ if (!(alloc) && \ (!garbage_collect_with_gvl(objspace, 1, 1, GPR_FLAG_MALLOC) || /* full mark && immediate sweep */ \ !(alloc))) { \ diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index 00a49418ac..5181e9db9f 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -312,4 +312,22 @@ class TestGc < Test::Unit::TestCase def test_verify_internal_consistency assert_nil(GC.verify_internal_consistency) end + + def test_gc_stress_on_realloc + assert_normal_exit(<<-'end;', '[Bug #9859]') + class C + def initialize + @a = nil + @b = nil + @c = nil + @d = nil + @e = nil + @f = nil + end + end + + GC.stress = true + C.new + end; + end end