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/