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

ruby-changes:63741

From: Aaron <ko1@a...>
Date: Wed, 25 Nov 2020 05:38:36 +0900 (JST)
Subject: [ruby-changes:63741] 490b57783d (master): Disable read barrier on explicit compaction request

https://git.ruby-lang.org/ruby.git/commit/?id=490b57783d

From 490b57783d80f0c5f7882c66d9fb6aa02713c9a5 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Tue, 24 Nov 2020 10:45:12 -0800
Subject: Disable read barrier on explicit compaction request

We don't need a read barrier when the user calls `GC.compact` because we
don't allow allocations during GC, and all references should be "live"

diff --git a/gc.c b/gc.c
index 3dbeeec..ed98792 100644
--- a/gc.c
+++ b/gc.c
@@ -682,7 +682,7 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L682
 	unsigned int dont_gc : 1;
 	unsigned int dont_incremental : 1;
 	unsigned int during_gc : 1;
-        unsigned int during_compacting : 1;
+        unsigned int during_compacting : 2;
 	unsigned int gc_stressful: 1;
 	unsigned int has_hook: 1;
 	unsigned int during_minor_gc : 1;
@@ -4389,6 +4389,11 @@ static VALUE gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free); https://github.com/ruby/ruby/blob/trunk/gc.c#L4389
 static void
 lock_page_body(rb_objspace_t *objspace, struct heap_page_body *body)
 {
+    /* 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;
+    }
 #if defined(_WIN32)
     DWORD old_protect;
 
@@ -4405,6 +4410,11 @@ lock_page_body(rb_objspace_t *objspace, struct heap_page_body *body) https://github.com/ruby/ruby/blob/trunk/gc.c#L4410
 static void
 unlock_page_body(rb_objspace_t *objspace, struct heap_page_body *body)
 {
+    /* 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;
+    }
 #if defined(_WIN32)
     DWORD old_protect;
 
@@ -7030,7 +7040,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark) https://github.com/ruby/ruby/blob/trunk/gc.c#L7040
 #endif
 	objspace->flags.during_minor_gc = FALSE;
         if (ruby_enable_autocompact) {
-            objspace->flags.during_compacting = TRUE;
+            objspace->flags.during_compacting |= TRUE;
         }
 	objspace->profile.major_gc_count++;
 	objspace->rgengc.uncollectible_wb_unprotected_objects = 0;
@@ -8057,7 +8067,9 @@ gc_start(rb_objspace_t *objspace, int reason) https://github.com/ruby/ruby/blob/trunk/gc.c#L8067
 
     /* reason may be clobbered, later, so keep set immediate_sweep here */
     objspace->flags.immediate_sweep = !!((unsigned)reason & GPR_FLAG_IMMEDIATE_SWEEP);
-    objspace->flags.during_compacting = !!((unsigned)reason & GPR_FLAG_COMPACT);
+
+    /* Explicitly enable compaction (GC.compact) */
+    objspace->flags.during_compacting = (!!((unsigned)reason & GPR_FLAG_COMPACT) << 1);
 
     if (!heap_allocated_pages) return FALSE; /* heap is not ready */
     if (!(reason & GPR_FLAG_METHOD) && !ready_to_gc(objspace)) return TRUE; /* GC is not allowed */
@@ -9248,6 +9260,19 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data) https://github.com/ruby/ruby/blob/trunk/gc.c#L9260
 }
 
 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. */
+    gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
+
+    return gc_compact_stats(ec, self);
+}
+
+static VALUE
 gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE double_heap, VALUE toward_empty)
 {
     rb_objspace_t *objspace = &rb_objspace;
diff --git a/gc.rb b/gc.rb
index d2b0d8e..4e0faaf 100644
--- a/gc.rb
+++ b/gc.rb
@@ -199,8 +199,7 @@ module GC https://github.com/ruby/ruby/blob/trunk/gc.rb#L199
   end
 
   def self.compact
-    Primitive.gc_start_internal true, true, true, true
-    Primitive.gc_compact_stats
+    Primitive.gc_compact
   end
 
   # call-seq:
-- 
cgit v0.10.2


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

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