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

ruby-changes:63748

From: Aaron <ko1@a...>
Date: Wed, 25 Nov 2020 14:30:44 +0900 (JST)
Subject: [ruby-changes:63748] fed67fe6b2 (master): Revert "Disable auto compaction on platforms that can't support it"

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

From fed67fe6b277361940e3357c8b1ffa455d7f2339 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Tue, 24 Nov 2020 21:29:45 -0800
Subject: Revert "Disable auto compaction on platforms that can't support it"

This reverts commit 63ad55cd882e4010fe313d271af006a430b5ffa8.

Revert "Disable read barrier on explicit compaction request"

This reverts commit 490b57783d80f0c5f7882c66d9fb6aa02713c9a5.

diff --git a/gc.c b/gc.c
index d5ad476..5573ee5 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 : 2;
+        unsigned int during_compacting : 1;
 	unsigned int gc_stressful: 1;
 	unsigned int has_hook: 1;
 	unsigned int during_minor_gc : 1;
@@ -3090,17 +3090,6 @@ Init_heap(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L3090
 {
     rb_objspace_t *objspace = &rb_objspace;
 
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
-    /* If Ruby's heap pages are not a multiple of the system page size, we
-     * cannot use mprotect for the read barrier, so we must disable automatic
-     * compaction. */
-    int pagesize;
-    pagesize = (int)sysconf(_SC_PAGE_SIZE);
-    if ((HEAP_PAGE_SIZE % pagesize) != 0) {
-        ruby_enable_autocompact = 0;
-    }
-#endif
-
     objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL);
     objspace->id_to_obj_tbl = st_init_table(&object_id_hash_type);
     objspace->obj_to_id_tbl = st_init_numtable();
@@ -4400,11 +4389,6 @@ 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;
 
@@ -4421,11 +4405,6 @@ lock_page_body(rb_objspace_t *objspace, struct heap_page_body *body) https://github.com/ruby/ruby/blob/trunk/gc.c#L4405
 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;
 
@@ -7051,7 +7030,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark) https://github.com/ruby/ruby/blob/trunk/gc.c#L7030
 #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;
@@ -8078,9 +8057,7 @@ gc_start(rb_objspace_t *objspace, int reason) https://github.com/ruby/ruby/blob/trunk/gc.c#L8057
 
     /* reason may be clobbered, later, so keep set immediate_sweep here */
     objspace->flags.immediate_sweep = !!((unsigned)reason & GPR_FLAG_IMMEDIATE_SWEEP);
-
-    /* Explicitly enable compaction (GC.compact) */
-    objspace->flags.during_compacting = (!!((unsigned)reason & GPR_FLAG_COMPACT) << 1);
+    objspace->flags.during_compacting = !!((unsigned)reason & GPR_FLAG_COMPACT);
 
     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 */
@@ -9271,19 +9248,6 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data) https://github.com/ruby/ruby/blob/trunk/gc.c#L9248
 }
 
 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;
@@ -9901,16 +9865,6 @@ gc_disable(rb_execution_context_t *ec, VALUE _) https://github.com/ruby/ruby/blob/trunk/gc.c#L9865
 static VALUE
 gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v)
 {
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
-    /* If Ruby's heap pages are not a multiple of the system page size, we
-     * cannot use mprotect for the read barrier, so we must disable automatic
-     * compaction. */
-    int pagesize;
-    pagesize = (int)sysconf(_SC_PAGE_SIZE);
-    if ((HEAP_PAGE_SIZE % pagesize) != 0) {
-        rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform");
-    }
-#endif
     ruby_enable_autocompact = RTEST(v);
     return v;
 }
diff --git a/gc.rb b/gc.rb
index 4e0faaf..d2b0d8e 100644
--- a/gc.rb
+++ b/gc.rb
@@ -199,7 +199,8 @@ module GC https://github.com/ruby/ruby/blob/trunk/gc.rb#L199
   end
 
   def self.compact
-    Primitive.gc_compact
+    Primitive.gc_start_internal true, true, true, true
+    Primitive.gc_compact_stats
   end
 
   # call-seq:
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
index 4a8cff3..3aad9e6 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -1,82 +1,56 @@ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc_compact.rb#L1
 # frozen_string_literal: true
 require 'test/unit'
 require 'fiddle'
-require 'etc'
 
 class TestGCCompact < Test::Unit::TestCase
-  class AutoCompact < Test::Unit::TestCase
-    def setup
-      skip "autocompact not supported on this platform" unless supports_auto_compact?
-      super
-    end
-
-    def test_enable_autocompact
-      before = GC.auto_compact
-      GC.auto_compact = true
-      assert GC.auto_compact
-    ensure
-      GC.auto_compact = before
-    end
-
-    def test_disable_autocompact
-      before = GC.auto_compact
-      GC.auto_compact = false
-      refute GC.auto_compact
-    ensure
-      GC.auto_compact = before
-    end
-
-    def test_major_compacts
-      before = GC.auto_compact
-      GC.auto_compact = true
-      compact = GC.stat :compact_count
-      GC.start
-      assert_operator GC.stat(:compact_count), :>, compact
-    ensure
-      GC.auto_compact = before
-    end
-
-    def test_implicit_compaction_does_something
-      before = GC.auto_compact
-      list = []
-      list2 = []
-
-      # Try to make some fragmentation
-      500.times {
-        list << Object.new
-        Object.new
-        Object.new
-      }
-      count = GC.stat :compact_count
-      GC.auto_compact = true
-      loop do
-        break if count < GC.stat(:compact_count)
-        list2 << Object.new
-      end
-      compact_stats = GC.latest_compact_info
-      refute_predicate compact_stats[:considered], :empty?
-      refute_predicate compact_stats[:moved], :empty?
-    ensure
-      GC.auto_compact = before
-    end
+  def test_enable_autocompact
+    before = GC.auto_compact
+    GC.auto_compact = true
+    assert GC.auto_compact
+  ensure
+    GC.auto_compact = before
+  end
 
-    private
+  def test_disable_autocompact
+    before = GC.auto_compact
+    GC.auto_compact = false
+    refute GC.auto_compact
+  ensure
+    GC.auto_compact = before
+  end
 
-    def supports_auto_compact?
-      return true unless defined?(Etc::SC_PAGE_SIZE)
+  def test_major_compacts
+    before = GC.auto_compact
+    GC.auto_compact = true
+    compact = GC.stat :compact_count
+    GC.start
+    assert_operator GC.stat(:compact_count), :>, compact
+  ensure
+    GC.auto_compact = before
+  end
 
-      begin
-        return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
-      rescue NotImplementedError
-      rescue ArgumentError
-      end
+  def test_implicit_compaction_does_something
+    before = GC.auto_compact
+    list = []
+    list2 = []
 
-      true
+    # Try to make some fragmentation
+    500.times {
+      list << Object.new
+      Object.new
+      Object.new
+    }
+    count = GC.stat :compact_count
+    GC.auto_compact = true
+    loop do
+      break if count < GC.stat(:compact_count)
+      list2 << Object.new
     end
-  end
-
-  def os_page_size
-    return true unless defined?(Etc::SC_PAGE_SIZE)
+    compact_stats = GC.latest_compact_info
+    refute_predicate compact_stats[:considered], :empty?
+    refute_predicate compact_stats[:moved], :empty?
+  ensure
+    GC.auto_compact = before
   end
 
   def test_gc_compact_stats
-- 
cgit v0.10.2


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

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