summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2019-05-23 11:21:16 +0900
committerKoichi Sasada <ko1@atdot.net>2019-05-23 11:26:33 +0900
commit136ae55892ae120bb94e4ff2d025c745fdaa1091 (patch)
treea2aa5d724bfc1973517d190706edf06232fc53f4
parent0eff21af8d03a9d2b881b9cce963262da3d952dc (diff)
Do not kick finalizers on rb_gc().
rb_gc() kicks gc_finalize_deferred(), which invokes finalizers. This means that any Ruby program can be run this point and it may be thread switching points and so on. However, it is difficult to think it invokes any Ruby programs. For example, `GC.compact` use `rb_gc()` to implement it, howver, any Ruby program must not be run on this timing. For this reason (it is difficult to image it run any Ruby program), I removed `gc_finalize_deferred()` line in rb_gc(). This patch solves GC.compact issue. [Bug #15809] and re-enable GC.compact test.
-rw-r--r--gc.c7
-rw-r--r--test/ruby/test_gc_compact.rb2
2 files changed, 5 insertions, 4 deletions
diff --git a/gc.c b/gc.c
index 438715337c..de5e9446f6 100644
--- a/gc.c
+++ b/gc.c
@@ -8171,7 +8171,11 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data)
void *poisoned = poisoned_object_p(v);
unpoison_object(v, false);
- if (BUILTIN_TYPE(v) != T_NONE) {
+ switch (BUILTIN_TYPE(v)) {
+ case T_NONE:
+ case T_ZOMBIE:
+ break;
+ default:
rb_objspace_reachable_objects_from(v, reachable_object_check_moved_i, (void *)v);
}
@@ -8309,7 +8313,6 @@ rb_gc(void)
int reason = GPR_FLAG_FULL_MARK | GPR_FLAG_IMMEDIATE_MARK |
GPR_FLAG_IMMEDIATE_SWEEP | GPR_FLAG_CAPI;
garbage_collect(objspace, reason);
- gc_finalize_deferred(objspace);
}
int
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
index d2b2c1bb47..5669fd3d6a 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -2,8 +2,6 @@
require 'test/unit'
require 'fiddle'
-return
-
class TestGCCompact < Test::Unit::TestCase
def memory_location(obj)
(Fiddle.dlwrap(obj) >> 1)