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

ruby-changes:66328

From: Aaron <ko1@a...>
Date: Wed, 26 May 2021 09:37:38 +0900 (JST)
Subject: [ruby-changes:66328] fc832ffbfa (master): Disable compaction on platforms that can't support it

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

From fc832ffbfaf581ff63ef40dc3f4ec5c8ff39aae6 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Tue, 25 May 2021 16:20:52 -0700
Subject: Disable compaction on platforms that can't support it

Manual compaction also requires a read barrier, so we need to disable
even manual compaction on platforms that don't support mprotect.

[Bug #17871]
---
 gc.c                         | 18 ++++++++++++++++++
 test/ruby/test_gc_compact.rb | 41 ++++++++++++++++++++++++++---------------
 2 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/gc.c b/gc.c
index 1d34917..64b16c9 100644
--- a/gc.c
+++ b/gc.c
@@ -9998,6 +9998,24 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data) https://github.com/ruby/ruby/blob/trunk/gc.c#L9998
 static VALUE
 gc_compact(rb_execution_context_t *ec, VALUE self)
 {
+#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 compaction. */
+    int pagesize;
+    pagesize = (int)sysconf(_SC_PAGE_SIZE);
+    if ((HEAP_PAGE_SIZE % pagesize) != 0) {
+        rb_raise(rb_eNotImpError, "Compaction isn't available on this platform");
+    }
+#endif
+
+    /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for
+     * the read barrier, so we must disable compaction. */
+#if !defined(__MINGW32__) && !defined(_WIN32)
+    if (!USE_MMAP_ALIGNED_ALLOC) {
+        rb_raise(rb_eNotImpError, "Compaction isn't available on this platform");
+    }
+#endif
+
     /* Run GC with compaction enabled */
     gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
 
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
index 8dfa66a..7d8bde0 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -4,12 +4,32 @@ require 'fiddle' https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc_compact.rb#L4
 require 'etc'
 
 class TestGCCompact < Test::Unit::TestCase
-  class AutoCompact < Test::Unit::TestCase
+  module SupportsCompact
     def setup
       skip "autocompact not supported on this platform" unless supports_auto_compact?
       super
     end
 
+    private
+
+    def supports_auto_compact?
+      return true unless defined?(Etc::SC_PAGE_SIZE)
+
+      begin
+        return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
+      rescue NotImplementedError
+      rescue ArgumentError
+      end
+
+      true
+    end
+  end
+
+  include SupportsCompact
+
+  class AutoCompact < Test::Unit::TestCase
+    include SupportsCompact
+
     def test_enable_autocompact
       before = GC.auto_compact
       GC.auto_compact = true
@@ -59,26 +79,17 @@ class TestGCCompact < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc_compact.rb#L79
     ensure
       GC.auto_compact = before
     end
-
-    private
-
-    def supports_auto_compact?
-      return true unless defined?(Etc::SC_PAGE_SIZE)
-
-      begin
-        return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
-      rescue NotImplementedError
-      rescue ArgumentError
-      end
-
-      true
-    end
   end
 
   def os_page_size
     return true unless defined?(Etc::SC_PAGE_SIZE)
   end
 
+  def setup
+    skip "autocompact not supported on this platform" unless supports_auto_compact?
+    super
+  end
+
   def test_gc_compact_stats
     list = []
 
-- 
cgit v1.1


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

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