[前][次][番号順一覧][スレッド一覧]

ruby-changes:64987

From: Aaron <ko1@a...>
Date: Fri, 22 Jan 2021 02:55:39 +0900 (JST)
Subject: [ruby-changes:64987] 0130e17a41 (master): Always enabled read barrier even on GC.compact

https://git.ruby-lang.org/ruby.git/commit/?id=0130e17a41

From 0130e17a410d60a10e7041ce98748b8de6946971 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Thu, 21 Jan 2021 09:52:56 -0800
Subject: Always enabled read barrier even on GC.compact

Some objects can survive the GC before compaction, but get collected in
the second compaction.  This means we could have objects reference
T_MOVED during "free" in the second, compacting GC.  If that is the
case, we need to invalidate those "moved" addresses.  Invalidation is
done via read barrier, so we need to make sure the read barrier is
active even during `GC.compact`.

This also means we don't actually need to do one GC before compaction,
we can just do the compaction and GC in one step.

diff --git a/gc.c b/gc.c
index 27cf65b..998f086 100644
--- a/gc.c
+++ b/gc.c
@@ -4761,12 +4761,8 @@ gc_compact_finish(rb_objspace_t *objspace, rb_heap_t *heap) https://github.com/ruby/ruby/blob/trunk/gc.c#L4761
 {
     GC_ASSERT(heap->sweeping_page == heap->compact_cursor);
 
-    /* If this is an explicit compaction (GC.compact), no read barrier was set
-     * so we don't need to unprotect pages or uninstall the SEGV handler */
-    if (!(objspace->flags.during_compacting >> 1)) {
-        gc_unprotect_pages(objspace, heap);
-        uninstall_handlers();
-    }
+    gc_unprotect_pages(objspace, heap);
+    uninstall_handlers();
 
     /* The mutator is allowed to run during incremental sweeping. T_MOVED
      * objects can get pushed on the stack and when the compaction process
@@ -5306,12 +5302,6 @@ gc_compact_start(rb_objspace_t *objspace, rb_heap_t *heap) https://github.com/ruby/ruby/blob/trunk/gc.c#L5302
     memset(objspace->rcompactor.considered_count_table, 0, T_MASK * sizeof(size_t));
     memset(objspace->rcompactor.moved_count_table, 0, T_MASK * sizeof(size_t));
 
-    /* If this is an explicit compaction (GC.compact), we don't need a read
-     * barrier, so just return early. */
-    if (objspace->flags.during_compacting >> 1) {
-        return;
-    }
-
     /* Set up read barrier for pages containing MOVED objects */
     install_handlers();
 }
@@ -9487,11 +9477,7 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data) https://github.com/ruby/ruby/blob/trunk/gc.c#L9477
 static VALUE
 gc_compact(rb_execution_context_t *ec, VALUE self)
 {
-    /* Clear the heap. */
-    gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qfalse);
-
-    /* At this point, all references are live and the mutator is not allowed
-     * to run, so we don't need a read barrier. */
+    /* Run GC with compaction enabled */
     gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
 
     return gc_compact_stats(ec, self);
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]