The package rpms/ruby.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/ruby.git/commit/?id=0cb6ae8bde3bb...
https://src.fedoraproject.org/cgit/rpms/ruby.git/commit/?id=e3f5520815cb7....
Change:
-%ifnarch ppc64le
+%ifnarch ppc64le
Thanks.
Full change:
============
commit f315aba60fabef27b1efe1ac592e0e5f639f89f6
Author: Jarek Prokop <jprokop(a)redhat.com>
Date: Fri Sep 2 10:21:43 2022 +0200
Disable Fiddle test cases making use of FFI closure.
Fiddle::Closure object is making use of FFI closure
from libffi. When such object is created (instantiated) in Ruby,
and then the process forks on an SELinux-enabled system, the memory
will become corrupted. That is usually not a problem until the
The garbage collector sweeps the object and tries to free it, in which case the
Ruby process will fail with signal SIGABRT.
Tests in test/fiddle/test_closure.rb, test/fiddle/test_func.rb,
and test/fiddle/test_function.rb use the `Fiddle::Closure` class
directly and fiddle/test_import.rb use the class indirectly through
`bind_function` method, therefore they are disabled to prevent
introducing the problematic object into the Ruby GC during test suite
execution instead of relying on that fork and subsequent
garbage collection will not happen.
If an FFI closure object is allocated in Ruby
and the `fork` function is used afterward, the memory
pointing to the closure gets corrupted, and if Ruby GC
tries to collect the object in that state, a SIGABRT
error occurs.
The minimal Ruby reproducer for the issue is the following:
~~~
$ cat fiddle_fork.rb
require 'fiddle/closure'
require 'fiddle/struct'
Fiddle::Closure.new(Fiddle::TYPE_VOID, [])
fork { }
GC.start
~~~
We allocate an unused Closure object,
so it is free for the GC to pick up. Before we call `GC.start`
we fork the process as that corrupts the memory.
Running this with ruby-3.1.2-167.fc37.x86_64 on SELinux enabled system:
~~~
$ ruby fiddle_fork.rb
Aborted (core dumped)
~~~
Such issues may appear at random (depending on the use of forking and GC)
in larger applications that use Fiddle::Closure but can be spotted by the
following functions appearing in the coredump backtrace:
~~~
0x00007f6284d3e5b3 in dlfree (mem=<optimized out>) at ../src/dlmalloc.c:4350
0x00007f6284d6d0b1 in dealloc () from /usr/lib64/ruby/fiddle.so
0x00007f6295e432ec in finalize_list () from /lib64/libruby.so.3.1
0x00007f6295e43420 in finalize_deferred.lto_priv () from /lib64/libruby.so.3.1
0x00007f6295e4ff1c in gc_start_internal.lto_priv () from /lib64/libruby.so.3.1
~~~
Possible solutions to prevent Ruby from crashing:
* Do not use Fiddle::Closure.
* Use the Fiddle::Closure object only in isolated subprocess that
will not fork further.
* Enable static trampolines in libffi as noted in bugzilla comment:
<
https://bugzilla.redhat.com/show_bug.cgi?id=2040380#c9>
See related discussion on
<
https://bugzilla.redhat.com/show_bug.cgi?id=2040380>
Ruby upstream ticket:
<
https://bugs.ruby-lang.org/issues/18914>
Ruby Fiddle ticket:
<
https://github.com/ruby/fiddle/issues/102>
diff --git a/ruby.spec b/ruby.spec
index 6b1a582..9a2c12f 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -22,7 +22,7 @@
%endif
-%global release 168
+%global release 169
%{!?release_string:%define release_string
%{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
# The RubyGems library has to stay out of Ruby directory tree, since the
@@ -991,6 +991,9 @@ DISABLE_TESTS="$DISABLE_TESTS -n
!/TestReadline#test_interrupt_in_other_thread/"
# other components are fixed.
#
https://bugzilla.redhat.com/show_bug.cgi?id=2040380
mv test/fiddle/test_import.rb{,.disable}
+mv test/fiddle/test_closure.rb{,.disable}
+DISABLE_TESTS="$DISABLE_TESTS -n !/Fiddle::TestFunc#test_qsort1/"
+DISABLE_TESTS="$DISABLE_TESTS -n !/Fiddle::TestFunction#test_argument_count/"
# Give an option to increase the timeout in tests.
#
https://bugs.ruby-lang.org/issues/16921
@@ -1546,6 +1549,10 @@ mv test/fiddle/test_import.rb{,.disable}
%changelog
+* Fri Sep 02 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-169
+- Disable fiddle tests that use FFI closures.
+ Related: rhbz#2040380
+
* Mon Aug 29 2022 Jun Aruga <jaruga(a)redhat.com> - 3.1.2-168
- Make RDoc soft dependnecy in IRB.
Resolves: rhbz#2119964
commit 48c6f880d9e28c093a51b4bf33ef8c5c9d6d8c0a
Author: Jun Aruga <jaruga(a)redhat.com>
Date: Fri Aug 26 15:58:52 2022 +0200
Add IRB to ruby-bundled-gems recommends.
Resolves: rhbz#2120562
diff --git a/ruby.spec b/ruby.spec
index 0fe9880..6b1a582 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -500,6 +500,8 @@ many machines, systematically and repeatably.
%package bundled-gems
Summary: Bundled gems which are part of Ruby StdLib
Requires: ruby(rubygems) >= %{rubygems_version}
+# Runtime dependency of rubygem(debug).
+Recommends: rubygem(irb) >= %{irb_version}
Provides: rubygem(net-ftp) = %{net_ftp_version}
Provides: rubygem(net-imap) = %{net_imap_version}
Provides: rubygem(net-pop) = %{net_pop_version}
@@ -1547,6 +1549,8 @@ mv test/fiddle/test_import.rb{,.disable}
* Mon Aug 29 2022 Jun Aruga <jaruga(a)redhat.com> - 3.1.2-168
- Make RDoc soft dependnecy in IRB.
Resolves: rhbz#2119964
+- Add IRB to ruby-bundled-gems recommends.
+ Resolves: rhbz#2120562
* Wed Aug 24 2022 Jun Aruga <jaruga(a)redhat.com> - 3.1.2-168
- Fix tests with Europe/Amsterdam pre-1970 time on tzdata version 2022b.
commit dd1972cffbe069bcbca4bebff7e50358b82bee7e
Author: Jun Aruga <jaruga(a)redhat.com>
Date: Fri Aug 26 14:36:43 2022 +0200
Make RDoc soft dependnecy in IRB.
Resolves: rhbz#2119964
diff --git a/ruby-irb-1.4.1-drop-rdoc-hard-dep.patch
b/ruby-irb-1.4.1-drop-rdoc-hard-dep.patch
new file mode 100644
index 0000000..711c514
--- /dev/null
+++ b/ruby-irb-1.4.1-drop-rdoc-hard-dep.patch
@@ -0,0 +1,24 @@
+From 54c8df06ff9e161012f89d19a4e3aa2e0e37e1b0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch(a)redhat.com>
+Date: Tue, 23 Aug 2022 10:41:28 +0200
+Subject: [PATCH] Drop hard dependency on RDoc.
+
+This has been introduced in 026700499dfd640b2072d7bf0370247a98d5ac40,
+but it seems that this is just be mistake, otherwise the later handling
+of `LoadError` would not be needed.
+---
+ lib/irb/input-method.rb | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb
+index fd68239e..a8227caa 100644
+--- a/lib/irb/input-method.rb
++++ b/lib/irb/input-method.rb
+@@ -14,7 +14,6 @@
+ require_relative 'completion'
+ require 'io/console'
+ require 'reline'
+-require 'rdoc'
+
+ module IRB
+ STDIN_FILE_NAME = "(line)" # :nodoc:
diff --git a/ruby-irb-1.4.1-set-rdoc-soft-dep.patch
b/ruby-irb-1.4.1-set-rdoc-soft-dep.patch
new file mode 100644
index 0000000..0156fe0
--- /dev/null
+++ b/ruby-irb-1.4.1-set-rdoc-soft-dep.patch
@@ -0,0 +1,41 @@
+From b24852058fc87c940252c8a711c60ae2eb298082 Mon Sep 17 00:00:00 2001
+From: Jun Aruga <jaruga(a)redhat.com>
+Date: Thu, 25 Aug 2022 20:11:34 +0200
+Subject: [PATCH] Require RDoc in `input-method.rb` again in a limited scope.
+
+RDoc is implemented as soft dependency in IRB. See how the rdoc is required in
+the files. I reverted the commit below.
+
+```
+$ grep -ril rdoc lib/
+lib/irb/cmd/help.rb
+lib/irb/completion.rb
+lib/irb/easter-egg.rb
+lib/irb/input-method.rb
+```
+
+---
+
+Revert "Remove `require` in signal handler to avoid ThreadError"
+
+This reverts commit 5f749c613c895cf1b11b5e4cbd1205363bc58028.
+---
+ lib/irb/input-method.rb | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb
+index a8227ca..b77fd32 100644
+--- a/lib/irb/input-method.rb
++++ b/lib/irb/input-method.rb
+@@ -320,6 +320,11 @@ def auto_indent(&block)
+ [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
+ [226, 136, 130] # The "∂" that appears when Alt+d in pressed on
iTerm2.
+ ]
++ begin
++ require 'rdoc'
++ rescue LoadError
++ return nil
++ end
+
+ if just_cursor_moving and completion_journey_data.nil?
+ return nil
diff --git a/ruby.spec b/ruby.spec
index e260189..0fe9880 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -202,6 +202,12 @@ Patch25:
ruby-rubygems-3.3.8-Resolve-cleaned-up-error-with-temporary-gemhome.pat
# Fix tests with Europe/Amsterdam pre-1970 time on tzdata version 2022b.
#
https://github.com/ruby/spec/pull/939
Patch26: ruby-spec-Fix-tests-on-tzdata-2022b.patch
+# Drop hard dependency on RDoc in IRB.
+#
https://github.com/ruby/irb/pull/393
+Patch27: ruby-irb-1.4.1-drop-rdoc-hard-dep.patch
+# Set soft dependency on RDoc in input-method.rb in IRB.
+#
https://github.com/ruby/irb/pull/395
+Patch28: ruby-irb-1.4.1-set-rdoc-soft-dep.patch
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Suggests: rubypick
@@ -354,6 +360,7 @@ Requires: ruby(rubygems) >= %{rubygems_version}
# ruby-default-gems is required to run irb.
#
https://bugs.ruby-lang.org/issues/16951
Requires: ruby-default-gems >= %{ruby_version}
+Recommends: rubygem(rdoc) >= %{rdoc_version}
Provides: irb = %{version}-%{release}
Provides: rubygem(irb) = %{version}-%{release}
# Obsoleted by Ruby 2.6 in F30 timeframe.
@@ -679,6 +686,8 @@ find .bundle/gems -name '*-[0-9]*.gemspec' -exec cp -t
.bundle/specifications/ {
%patch24 -p1
%patch25 -p1
%patch26 -p1
+%patch27 -p1
+%patch28 -p1
# Provide an example of usage of the tapset:
cp -a %{SOURCE3} .
@@ -1535,6 +1544,10 @@ mv test/fiddle/test_import.rb{,.disable}
%changelog
+* Mon Aug 29 2022 Jun Aruga <jaruga(a)redhat.com> - 3.1.2-168
+- Make RDoc soft dependnecy in IRB.
+ Resolves: rhbz#2119964
+
* Wed Aug 24 2022 Jun Aruga <jaruga(a)redhat.com> - 3.1.2-168
- Fix tests with Europe/Amsterdam pre-1970 time on tzdata version 2022b.
Resolves: rhbz#2120354
commit 7e7c11dd81fde25ce7ef9b4e665fe8e8afa357c4
Author: Jun Aruga <jaruga(a)redhat.com>
Date: Wed Aug 24 13:44:41 2022 +0200
Fix tests with Europe/Amsterdam pre-1970 time on tzdata version 2022b.
Resolves: rhbz#2120354
diff --git a/ruby-spec-Fix-tests-on-tzdata-2022b.patch
b/ruby-spec-Fix-tests-on-tzdata-2022b.patch
new file mode 100644
index 0000000..19386d9
--- /dev/null
+++ b/ruby-spec-Fix-tests-on-tzdata-2022b.patch
@@ -0,0 +1,40 @@
+From 7e9ec8a20b0f7469b415283d2ec0c22087f8eb2b Mon Sep 17 00:00:00 2001
+From: Jun Aruga <jaruga(a)redhat.com>
+Date: Wed, 24 Aug 2022 12:02:56 +0200
+Subject: [PATCH] Fix tests with Europe/Amsterdam pre-1970 time on tzdata
+ version 2022b.
+
+The Time Zone Database (tzdata) changed the pre-1970 timestamps in some zones
+including Europe/Amsterdam on tzdata version 2022b or later.
+See
<
https://github.com/eggert/tz/commit/35fa37fbbb152f5dbed4fd5edfdc968e3584f...;.
+
+The tzdata RPM package maintainer on Fedora project suggested changing the Ruby
+test, because the change is intentional.
+See <
https://bugzilla.redhat.com/show_bug.cgi?id=2118259#c1>.
+
+We use post-1970 time test data to simplify the test.
+---
+ core/time/shared/local.rb | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/spec/ruby/core/time/shared/local.rb b/spec/ruby/core/time/shared/local.rb
+index 43f331c4c..c4aa7a7ea 100644
+--- a/spec/ruby/core/time/shared/local.rb
++++ b/spec/ruby/core/time/shared/local.rb
+@@ -8,10 +8,10 @@ describe :time_local, shared: true do
+
+ platform_is_not :windows do
+ describe "timezone changes" do
+- it "correctly adjusts the timezone change to 'CEST' on
'Europe/Amsterdam'" do
++ it "correctly adjusts the timezone change to 'CET' on
'Europe/Amsterdam'" do
+ with_timezone("Europe/Amsterdam") do
+- Time.send(@method, 1940, 5, 16).to_a.should ==
+- [0, 40, 1, 16, 5, 1940, 4, 137, true, "CEST"]
++ Time.send(@method, 1970, 5, 16).to_a.should ==
++ [0, 0, 0, 16, 5, 1970, 6, 136, false, "CET"]
+ end
+ end
+ end
+--
+2.36.1
+
diff --git a/ruby.spec b/ruby.spec
index 7bdb04c..e260189 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -22,7 +22,7 @@
%endif
-%global release 166
+%global release 168
%{!?release_string:%define release_string
%{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
# The RubyGems library has to stay out of Ruby directory tree, since the
@@ -199,6 +199,9 @@ Patch24: ruby-3.2.0-Detect-compaction-support-during-runtime.patch
#
https://github.com/rpm-software-management/rpm/pull/2080
#
https://github.com/rubygems/rubygems/pull/5372
Patch25: ruby-rubygems-3.3.8-Resolve-cleaned-up-error-with-temporary-gemhome.patch
+# Fix tests with Europe/Amsterdam pre-1970 time on tzdata version 2022b.
+#
https://github.com/ruby/spec/pull/939
+Patch26: ruby-spec-Fix-tests-on-tzdata-2022b.patch
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Suggests: rubypick
@@ -675,6 +678,7 @@ find .bundle/gems -name '*-[0-9]*.gemspec' -exec cp -t
.bundle/specifications/ {
%patch23 -p1
%patch24 -p1
%patch25 -p1
+%patch26 -p1
# Provide an example of usage of the tapset:
cp -a %{SOURCE3} .
@@ -1531,6 +1535,10 @@ mv test/fiddle/test_import.rb{,.disable}
%changelog
+* Wed Aug 24 2022 Jun Aruga <jaruga(a)redhat.com> - 3.1.2-168
+- Fix tests with Europe/Amsterdam pre-1970 time on tzdata version 2022b.
+ Resolves: rhbz#2120354
+
* Mon Jul 25 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-167
- Fix directory permissions in one of the rubygems tests.
commit b465ba7a5ef5ad32e626de0dc18791046d209534
Author: Jarek Prokop <jprokop(a)redhat.com>
Date: Mon Jul 11 13:02:25 2022 +0200
Fix Ruby build failing due to unremovable tmp subdirectory.
RPM 4.18.0-beta1 or later versions remove the build directory
automatically, the build fails on removing temporary directories with
the missing 'w' bit.
RubyGems contain this patch since version 3.3.8.
This was merged to ruby_3_1 branch in upstream ruby, but it is not
included in the v3_1_2 tag, so new Ruby 3.1 release should contain this
change.
Relevant RPM upstream PR:
https://github.com/rpm-software-management/rpm/pull/2080
Relevant bug:
https://bugzilla.redhat.com/show_bug.cgi?id=2105393
diff --git a/ruby-rubygems-3.3.8-Resolve-cleaned-up-error-with-temporary-gemhome.patch
b/ruby-rubygems-3.3.8-Resolve-cleaned-up-error-with-temporary-gemhome.patch
new file mode 100644
index 0000000..66c3382
--- /dev/null
+++ b/ruby-rubygems-3.3.8-Resolve-cleaned-up-error-with-temporary-gemhome.patch
@@ -0,0 +1,22 @@
+From 623162ad2bb3b589bddcc32616492a2bc4651726 Mon Sep 17 00:00:00 2001
+From: Hiroshi SHIBATA <hsbt(a)ruby-lang.org>
+Date: Tue, 22 Feb 2022 11:58:54 +0900
+Subject: [PATCH] Resolve cleaned-up error with temporary gemhome
+
+---
+ test/rubygems/test_gem_commands_setup_command.rb | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/test/rubygems/test_gem_commands_setup_command.rb
b/test/rubygems/test_gem_commands_setup_command.rb
+index 5cf94a1dc99..934c76b1d1a 100644
+--- a/test/rubygems/test_gem_commands_setup_command.rb
++++ b/test/rubygems/test_gem_commands_setup_command.rb
+@@ -274,6 +274,8 @@ def test_install_default_bundler_gem_with_destdir_flag
+ spec.executables.each do |e|
+ assert_path_exist File.join destdir, @gemhome.gsub(/^[a-zA-Z]:/, ''),
'gems', spec.full_name, spec.bindir, e
+ end
++ ensure
++ FileUtils.chmod "+w", @gemhome
+ end
+
+ def test_install_default_bundler_gem_with_destdir_and_prefix_flags
diff --git a/ruby.spec b/ruby.spec
index 3cbd793..7bdb04c 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -192,6 +192,13 @@ Patch23:
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.pat
#
https://github.com/ruby/ruby/pull/6019
#
https://github.com/ruby/ruby/commit/2c190863239bee3f54cfb74b16bb6ea4cae6ed20
Patch24: ruby-3.2.0-Detect-compaction-support-during-runtime.patch
+# RPM 4.18.0-beta1 or later versions remove the build directory automatically
+# on successful build, the build then fails on removing temporary directories
+# that are missing the 'w' bit.
+#
https://bugzilla.redhat.com/show_bug.cgi?id=2105393
+#
https://github.com/rpm-software-management/rpm/pull/2080
+#
https://github.com/rubygems/rubygems/pull/5372
+Patch25: ruby-rubygems-3.3.8-Resolve-cleaned-up-error-with-temporary-gemhome.patch
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Suggests: rubypick
@@ -667,6 +674,7 @@ find .bundle/gems -name '*-[0-9]*.gemspec' -exec cp -t
.bundle/specifications/ {
%patch22 -p1
%patch23 -p1
%patch24 -p1
+%patch25 -p1
# Provide an example of usage of the tapset:
cp -a %{SOURCE3} .
@@ -1523,6 +1531,9 @@ mv test/fiddle/test_import.rb{,.disable}
%changelog
+* Mon Jul 25 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-167
+- Fix directory permissions in one of the rubygems tests.
+
* Thu Jun 16 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-166
- Detect compaction support during run time.
commit 0cb6ae8bde3bbd44b10c8e2f7d8546ed9485f013
Author: Jarek Prokop <jprokop(a)redhat.com>
Date: Thu Jun 16 13:00:59 2022 +0200
Define the GC compaction support during run time.
Previous commit changed GC compaction methods to not be implemented
when not supported. However, that commit only does compile time checks,
but there are additional compaction support checks during run time.
This commit changes it so that GC compaction methods aren't defined
also during run time if the platform does not support GC compaction.
The patch is manually backported from following change set:
https://github.com/ruby/ruby/pull/6019
https://github.com/ruby/ruby/commit/2c190863239bee3f54cfb74b16bb6ea4cae6ed20
To apply the patch included with this commit,
first apply
`ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch`
and then apply the `ruby-3.2.0-detect_compaction_support_during_runtime.patch`.
Related upstream issue:
https://bugs.ruby-lang.org/issues/18829
diff --git a/ruby-3.2.0-Detect-compaction-support-during-runtime.patch
b/ruby-3.2.0-Detect-compaction-support-during-runtime.patch
new file mode 100644
index 0000000..fd8162f
--- /dev/null
+++ b/ruby-3.2.0-Detect-compaction-support-during-runtime.patch
@@ -0,0 +1,293 @@
+From 4d9cc9afa47981520d991d19fd78b322f1ba9f2a Mon Sep 17 00:00:00 2001
+From: Jarek Prokop <jprokop(a)redhat.com>
+Date: Wed, 22 Jun 2022 01:03:49 +0200
+Subject: [PATCH] Detect compaction support during runtime.
+
+The patch is created by backporting 3 commits from
+the upstream Ruby master branch in the chronological order below.
+
+https://github.com/ruby/ruby/commit/52d42e702375446746164a0251e1a10bce813b78
+https://github.com/ruby/ruby/commit/79eaaf2d0b641710613f16525e4b4c439dfe854e
+https://github.com/ruby/ruby/commit/2c190863239bee3f54cfb74b16bb6ea4cae6ed20
+
+== How to create this patch ==
+
+Download Ruby source code.
+```
+$ git clone
https://github.com/ruby/ruby.git
+$ cd ruby
+```
+
+First create a commit squashed from the 3 commits above.
+Checkout the second commmit above, and create a temporary branch.
+```
+$ git checkout 79eaaf2d0b641710613f16525e4b4c439dfe854e
+$ git checkout -b wip/detect-compaction-runtime-tmp
+```
+
+Cherry pick the third commit on the second commit.
+```
+$ git cherry-pick 2c190863239bee3f54cfb74b16bb6ea4cae6ed20
+```
+
+Squash the last 3 commits on the branch.
+```
+$ git rebase -i 2223eb082afa6d05321b69df783d4133b9aacba6
+```
+
+Then checkout Ruby 3.1.2 branch.
+Create a new branch.
+Merge the Fedora Ruby's
+ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch.
+```
+$ git checkout v3_1_2
+$ git checkout -b wip/detect-compaction-runtime
+$ patch -p1 <
+~/fed/ruby/ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
+$ git add gc.c gc.rb test/ruby/test_gc_compact.rb
+$ git commit
+```
+
+Merge the squashed one commit on the
+`wip/detect-compaction-runtime-tmp` branch
+into the `wip/detect-compaction-runtime` branch.
+```
+$ git cherry-pick <the squashed commit above>
+```
+
+Fix conflicts seeing the difference by `git show <the squashed commit
+above>`
+on another terminal.
+```
+$ vi gc.c
+$ git add gc.c
+$ git commit
+```
+
+== Notes for the patch ==
+
+```
++# define GC_COMPACTION_SUPPORTED (GC_CAN_COMPILE_COMPACTION &&
USE_MMAP_ALIGNED_ALLOC)
+```
+
+We use the USE_MMAP_ALIGNED_ALLOC instead of HEAP_PAGE_ALLOC_USE_MMAP on
+the line above. Because while the Ruby on the master branch replaced the
+USE_MMAP_ALIGNED_ALLOC with HEAP_PAGE_ALLOC_USE_MMAP, Ruby 3.1.2 doesn't.
+See
<
https://github.com/ruby/ruby/commit/fe21b7794af0cdb7ebd502e2c0da38c68fd89...;.
+
+
+```
++ rb_define_singleton_method(rb_mGC, "verify_compaction_references",
gc_verify_compaction_references, -1);
+```
+
+We added the line in the case that GC_COMPACTION_SUPPORTED is true.
+Because while the Ruby on the master branch defines the
+GC.verify_compaction_references in the gc.rb in
+the case that GC_COMPACTION_SUPPORTED is true, Ruby 3.1.2
+doesn't define it in the gc.rb.
+See
<
https://github.com/ruby/ruby/commit/b96a3a6fd2093e1dbea5491c002da515652dd...;.
+
+
+```
++ OPT(GC_COMPACTION_SUPPORTED);
+```
+
+We added the line to expose the C macro to Ruby level.
+In Ruby the macro existance can then be checked like so:
+```Ruby
+GC::OPTS.include?("GC_COMPACTION_SUPPORTED")
+```
+It will return `true` if the GC_COMPACTION_SUPPORTED evaluates to `true` on the
+C level, `false` otherwise.
+See
<
https://github.com/ruby/ruby/blob/b96a3a6fd2093e1dbea5491c002da515652dd34...
+
+== Original commit messages ==
+
+This is a combination of 3 commits.
+This is the 1st commit message:
+~~~
+Rename GC_COMPACTION_SUPPORTED
+
+Naming this macro GC_COMPACTION_SUPPORTED is misleading because it
+only checks whether compaction is supported at compile time.
+
+[Bug #18829]
+~~~
+
+This is the commit message #2:
+~~~
+Include runtime checks for compaction support
+
+Commit 0c36ba53192c5a0d245c9b626e4346a32d7d144e changed GC compaction
+methods to not be implemented when not supported. However, that commit
+only does compile time checks (which currently only checks for WASM),
+but there are additional compaction support checks during run time.
+
+This commit changes it so that GC compaction methods aren't defined
+during run time if the platform does not support GC compaction.
+
+[Bug #18829]
+~~~
+
+This is the commit message #3:
+~~~
+Suppress code unused unless GC_CAN_COMPILE_COMPACTION
+~~~
+---
+ gc.c | 63 +++++++++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 43 insertions(+), 20 deletions(-)
+
+diff --git a/gc.c b/gc.c
+index 1c35856c44..bff0666a17 100644
+--- a/gc.c
++++ b/gc.c
+@@ -4980,6 +4980,23 @@ gc_unprotect_pages(rb_objspace_t *objspace, rb_heap_t *heap)
+ static void gc_update_references(rb_objspace_t * objspace);
+ static void invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page);
+
++#ifndef GC_CAN_COMPILE_COMPACTION
++#if defined(__wasi__) /* WebAssembly doesn't support signals */
++# define GC_CAN_COMPILE_COMPACTION 0
++#else
++# define GC_CAN_COMPILE_COMPACTION 1
++#endif
++#endif
++
++#if defined(__MINGW32__) || defined(_WIN32)
++# define GC_COMPACTION_SUPPORTED 1
++#else
++/* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for
++ * the read barrier, so we must disable compaction. */
++# define GC_COMPACTION_SUPPORTED (GC_CAN_COMPILE_COMPACTION &&
USE_MMAP_ALIGNED_ALLOC)
++#endif
++
++#if GC_CAN_COMPILE_COMPACTION
+ static void
+ read_barrier_handler(uintptr_t address)
+ {
+@@ -5000,6 +5017,7 @@ read_barrier_handler(uintptr_t address)
+ }
+ RB_VM_LOCK_LEAVE();
+ }
++#endif
+
+ #if defined(_WIN32)
+ static LPTOP_LEVEL_EXCEPTION_FILTER old_handler;
+@@ -9250,13 +9268,7 @@ gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE
full_mark, VALUE
+
+ /* For now, compact implies full mark / sweep, so ignore other flags */
+ if (RTEST(compact)) {
+- /* 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
++ GC_ASSERT(GC_COMPACTION_SUPPORTED);
+
+ reason |= GPR_FLAG_COMPACT;
+ }
+@@ -9421,7 +9433,7 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t
slot_size)
+ return (VALUE)src;
+ }
+
+-#if GC_COMPACTION_SUPPORTED
++#if GC_CAN_COMPILE_COMPACTION
+ static int
+ compare_free_slots(const void *left, const void *right, void *dummy)
+ {
+@@ -10149,7 +10161,7 @@ gc_update_references(rb_objspace_t *objspace)
+ gc_update_table_refs(objspace, finalizer_table);
+ }
+
+-#if GC_COMPACTION_SUPPORTED
++#if GC_CAN_COMPILE_COMPACTION
+ /*
+ * call-seq:
+ * GC.latest_compact_info -> {:considered=>{:T_CLASS=>11},
:moved=>{:T_CLASS=>11}}
+@@ -10190,7 +10202,7 @@ gc_compact_stats(VALUE self)
+ # define gc_compact_stats rb_f_notimplement
+ #endif
+
+-#if GC_COMPACTION_SUPPORTED
++#if GC_CAN_COMPILE_COMPACTION
+ static void
+ root_obj_check_moved_i(const char *category, VALUE obj, void *data)
+ {
+@@ -10269,7 +10281,7 @@ gc_compact(VALUE self)
+ # define gc_compact rb_f_notimplement
+ #endif
+
+-#if GC_COMPACTION_SUPPORTED
++#if GC_CAN_COMPILE_COMPACTION
+ /*
+ * call-seq:
+ * GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
+@@ -10800,7 +10812,7 @@ gc_disable(rb_execution_context_t *ec, VALUE _)
+ return rb_gc_disable();
+ }
+
+-#if GC_COMPACTION_SUPPORTED
++#if GC_CAN_COMPILE_COMPACTION
+ /*
+ * call-seq:
+ * GC.auto_compact = flag
+@@ -10814,8 +10826,7 @@ gc_disable(rb_execution_context_t *ec, VALUE _)
+ static VALUE
+ gc_set_auto_compact(VALUE _, VALUE v)
+ {
+- /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for
+- * the read barrier, so we must disable automatic compaction. */
++ GC_ASSERT(GC_COMPACTION_SUPPORTED);
+
+ ruby_enable_autocompact = RTEST(v);
+ return v;
+@@ -10824,7 +10835,8 @@ gc_set_auto_compact(VALUE _, VALUE v)
+ # define gc_set_auto_compact rb_f_notimplement
+ #endif
+
+-#if GC_COMPACTION_SUPPORTED
++
++#if GC_CAN_COMPILE_COMPACTION
+ /*
+ * call-seq:
+ * GC.auto_compact -> true or false
+@@ -13696,11 +13708,21 @@ Init_GC(void)
+ rb_define_singleton_method(rb_mGC, "malloc_allocated_size",
gc_malloc_allocated_size, 0);
+ rb_define_singleton_method(rb_mGC, "malloc_allocations",
gc_malloc_allocations, 0);
+ #endif
+- rb_define_singleton_method(rb_mGC, "compact", gc_compact, 0);
+- rb_define_singleton_method(rb_mGC, "auto_compact", gc_get_auto_compact,
0);
+- rb_define_singleton_method(rb_mGC, "auto_compact=", gc_set_auto_compact,
1);
+- rb_define_singleton_method(rb_mGC, "latest_compact_info",
gc_compact_stats, 0);
+- rb_define_singleton_method(rb_mGC, "verify_compaction_references",
gc_verify_compaction_references, -1);
++ if (GC_COMPACTION_SUPPORTED) {
++ rb_define_singleton_method(rb_mGC, "compact", gc_compact, 0);
++ rb_define_singleton_method(rb_mGC, "auto_compact",
gc_get_auto_compact, 0);
++ rb_define_singleton_method(rb_mGC, "auto_compact=",
gc_set_auto_compact, 1);
++ rb_define_singleton_method(rb_mGC, "latest_compact_info",
gc_compact_stats, 0);
++ rb_define_singleton_method(rb_mGC, "verify_compaction_references",
gc_verify_compaction_references, -1);
++ }
++ else {
++ rb_define_singleton_method(rb_mGC, "compact", rb_f_notimplement, 0);
++ rb_define_singleton_method(rb_mGC, "auto_compact", rb_f_notimplement,
0);
++ rb_define_singleton_method(rb_mGC, "auto_compact=", rb_f_notimplement,
1);
++ rb_define_singleton_method(rb_mGC, "latest_compact_info",
rb_f_notimplement, 0);
++ /* When !GC_COMPACTION_SUPPORTED, this method is not defined in gc.rb */
++ rb_define_singleton_method(rb_mGC, "verify_compaction_references",
rb_f_notimplement, -1);
++ }
+
+ #if GC_DEBUG_STRESS_TO_CLASS
+ rb_define_singleton_method(rb_mGC, "add_stress_to_class",
rb_gcdebug_add_stress_to_class, -1);
+@@ -13724,6 +13746,7 @@ Init_GC(void)
+ OPT(MALLOC_ALLOCATED_SIZE);
+ OPT(MALLOC_ALLOCATED_SIZE_CHECK);
+ OPT(GC_PROFILE_DETAIL_MEMORY);
++ OPT(GC_COMPACTION_SUPPORTED);
+ #undef OPT
+ OBJ_FREEZE(opts);
+ }
+--
+2.36.1
+
diff --git a/ruby.spec b/ruby.spec
index eb3ac14..3cbd793 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -22,7 +22,7 @@
%endif
-%global release 165
+%global release 166
%{!?release_string:%define release_string
%{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
# The RubyGems library has to stay out of Ruby directory tree, since the
@@ -187,6 +187,11 @@ Patch22:
ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplemen
# diff -u {ruby-3.1.2,ruby}/gc.rbinc >
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
# diff -u {ruby-3.1.2,ruby}/miniprelude.c >>
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
Patch23: ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
+# Define the GC compaction support macro at run time.
+#
https://bugs.ruby-lang.org/issues/18829
+#
https://github.com/ruby/ruby/pull/6019
+#
https://github.com/ruby/ruby/commit/2c190863239bee3f54cfb74b16bb6ea4cae6ed20
+Patch24: ruby-3.2.0-Detect-compaction-support-during-runtime.patch
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Suggests: rubypick
@@ -661,6 +666,7 @@ find .bundle/gems -name '*-[0-9]*.gemspec' -exec cp -t
.bundle/specifications/ {
%patch21 -p1
%patch22 -p1
%patch23 -p1
+%patch24 -p1
# Provide an example of usage of the tapset:
cp -a %{SOURCE3} .
@@ -668,12 +674,6 @@ cp -a %{SOURCE3} .
%build
autoconf
-# Some platforms do not support compaction and upstream does not seem to provide the
-# right mechanism for the enablement of the preprocessor macros.
-#
https://bugs.ruby-lang.org/issues/18829
-%ifnarch ppc64le
-CFLAGS="%{build_cflags} -DGC_COMPACTION_SUPPORTED"
-%endif
%configure \
--with-rubylibprefix='%{ruby_libdir}' \
--with-archlibdir='%{_libdir}' \
@@ -1523,6 +1523,9 @@ mv test/fiddle/test_import.rb{,.disable}
%changelog
+* Thu Jun 16 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-166
+- Detect compaction support during run time.
+
* Tue Jun 07 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-165
- Define GC compaction methods as rb_f_notimplement on unsupported platforms.
commit e3f5520815cb72df5dd7581a352a1a069d727591
Author: Jarek Prokop <jprokop(a)redhat.com>
Date: Thu May 26 12:37:01 2022 +0200
Define compaction methods as rb_f_notimplement on unsupported platforms.
The patch implements the methods as rb_f_notimplement.
To test for compaction users can now use `GC.respond_to?(:compact)`.
The upstream patch relies on the macro `GC_COMPACTION_SUPPORTED`
that is defined when the `__wasi__` is false. The define is defined by
an arch conditional in the specfile, which is not optimal but works in our case.
https://github.com/ruby/ruby/commit/663833b08fbae8d92cb2245a729312b86aa33a35
https://bugs.ruby-lang.org/issues/18829
This also requires regenerating the gc.rbinc and miniprelude.c
since the patch touches gc.rb. This patch is available in
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch.
To regenerate the gc.rbinc and miniprelude.c files patch:
~~~
tar -Jxvf ./ruby-3.1.2.tar.xz
git clone
https://github.com/ruby/ruby.git
cd ruby && git checkout v3_1_2
patch -p1 <
../ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
./autogen.sh && ./configure
make gc.rbinc miniprelude.c
cd ..
diff -u {ruby-3.1.2,ruby}/gc.rbinc >
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
diff -u {ruby-3.1.2,ruby}/miniprelude.c >>
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
~~~
Uptream bug:
https://bugs.ruby-lang.org/issues/18779
Upstream PR:
https://github.com/ruby/ruby/pull/5934
diff --git
a/ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
b/ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
new file mode 100644
index 0000000..1e34def
--- /dev/null
+++ b/ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
@@ -0,0 +1,402 @@
+commit 6d1ca6737f31b2e24664a093f1827dd74a121a9f
+Author: Jarek Prokop <jprokop(a)redhat.com>
+Date: Thu May 26 11:28:13 2022 +0200
+
+ Gc ppc64le fix
+
+diff --git a/gc.c b/gc.c
+index ef9327df1f..1c35856c44 100644
+--- a/gc.c
++++ b/gc.c
+@@ -9421,6 +9421,7 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, size_t
slot_size)
+ return (VALUE)src;
+ }
+
++#if GC_COMPACTION_SUPPORTED
+ static int
+ compare_free_slots(const void *left, const void *right, void *dummy)
+ {
+@@ -9468,6 +9469,7 @@ gc_sort_heap_by_empty_slots(rb_objspace_t *objspace)
+ free(page_list);
+ }
+ }
++#endif
+
+ static void
+ gc_ref_update_array(rb_objspace_t * objspace, VALUE v)
+@@ -10147,8 +10149,21 @@ gc_update_references(rb_objspace_t *objspace)
+ gc_update_table_refs(objspace, finalizer_table);
+ }
+
++#if GC_COMPACTION_SUPPORTED
++/*
++ * call-seq:
++ * GC.latest_compact_info -> {:considered=>{:T_CLASS=>11},
:moved=>{:T_CLASS=>11}}
++ *
++ * Returns information about object moved in the most recent GC compaction.
++ *
++ * The returned hash has two keys :considered and :moved. The hash for
++ * :considered lists the number of objects that were considered for movement
++ * by the compactor, and the :moved hash lists the number of objects that
++ * were actually moved. Some objects can't be moved (maybe they were pinned)
++ * so these numbers can be used to calculate compaction efficiency.
++ */
+ static VALUE
+-gc_compact_stats(rb_execution_context_t *ec, VALUE self)
++gc_compact_stats(VALUE self)
+ {
+ size_t i;
+ rb_objspace_t *objspace = &rb_objspace;
+@@ -10171,7 +10186,11 @@ gc_compact_stats(rb_execution_context_t *ec, VALUE self)
+
+ return h;
+ }
++#else
++# define gc_compact_stats rb_f_notimplement
++#endif
+
++#if GC_COMPACTION_SUPPORTED
+ static void
+ root_obj_check_moved_i(const char *category, VALUE obj, void *data)
+ {
+@@ -10221,22 +10240,78 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride,
void *data)
+ return 0;
+ }
+
++/*
++ * call-seq:
++ * GC.compact
++ *
++ * This function compacts objects together in Ruby's heap. It eliminates
++ * unused space (or fragmentation) in the heap by moving objects in to that
++ * unused space. This function returns a hash which contains statistics about
++ * which objects were moved. See `GC.latest_gc_info` for details about
++ * compaction statistics.
++ *
++ * This method is implementation specific and not expected to be implemented
++ * in any implementation besides MRI.
++ *
++ * To test whether GC compaction is supported, use the idiom:
++ *
++ * GC.respond_to?(:compact)
++ */
+ static VALUE
+-gc_compact(rb_execution_context_t *ec, VALUE self)
++gc_compact(VALUE self)
+ {
+ /* Run GC with compaction enabled */
+- gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
++ gc_start_internal(NULL, self, Qtrue, Qtrue, Qtrue, Qtrue);
+
+- return gc_compact_stats(ec, self);
++ return gc_compact_stats(self);
+ }
++#else
++# define gc_compact rb_f_notimplement
++#endif
+
++#if GC_COMPACTION_SUPPORTED
++/*
++ * call-seq:
++ * GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
++ *
++ * Verify compaction reference consistency.
++ *
++ * This method is implementation specific. During compaction, objects that
++ * were moved are replaced with T_MOVED objects. No object should have a
++ * reference to a T_MOVED object after compaction.
++ *
++ * This function doubles the heap to ensure room to move all objects,
++ * compacts the heap to make sure everything moves, updates all references,
++ * then performs a full GC. If any object contains a reference to a T_MOVED
++ * object, that object should be pushed on the mark stack, and will
++ * make a SEGV.
++ */
+ static VALUE
+-gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE
double_heap, VALUE toward_empty)
++gc_verify_compaction_references(int argc, VALUE *argv, VALUE self)
+ {
+ rb_objspace_t *objspace = &rb_objspace;
++ VALUE kwargs, double_heap = Qfalse, toward_empty = Qfalse;
++ static ID id_toward, id_double_heap, id_empty;
++
++ if (!id_toward) {
++ id_toward = rb_intern("toward");
++ id_double_heap = rb_intern("double_heap");
++ id_empty = rb_intern("empty");
++ }
++
++ rb_scan_args(argc, argv, ":", &kwargs);
++ if (!NIL_P(kwargs)) {
++ if (rb_hash_has_key(kwargs, ID2SYM(id_toward))) {
++ VALUE toward = rb_hash_aref(kwargs, ID2SYM(id_toward));
++ toward_empty = (toward == ID2SYM(id_empty)) ? Qtrue : Qfalse;
++ }
++ if (rb_hash_has_key(kwargs, ID2SYM(id_double_heap))) {
++ double_heap = rb_hash_aref(kwargs, ID2SYM(id_double_heap));
++ }
++ }
+
+ /* Clear the heap. */
+- gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qfalse);
++ gc_start_internal(NULL, self, Qtrue, Qtrue, Qtrue, Qfalse);
+
+ RB_VM_LOCK_ENTER();
+ {
+@@ -10256,13 +10331,16 @@ gc_verify_compaction_references(rb_execution_context_t *ec,
VALUE self, VALUE do
+ }
+ RB_VM_LOCK_LEAVE();
+
+- gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
++ gc_start_internal(NULL, self, Qtrue, Qtrue, Qtrue, Qtrue);
+
+ objspace_reachable_objects_from_root(objspace, root_obj_check_moved_i, NULL);
+ objspace_each_objects(objspace, heap_check_moved_i, NULL, TRUE);
+
+- return gc_compact_stats(ec, self);
++ return gc_compact_stats(self);
+ }
++#else
++# define gc_verify_compaction_references rb_f_notimplement
++#endif
+
+ VALUE
+ rb_gc_start(void)
+@@ -10722,26 +10800,45 @@ gc_disable(rb_execution_context_t *ec, VALUE _)
+ return rb_gc_disable();
+ }
+
++#if GC_COMPACTION_SUPPORTED
++/*
++ * call-seq:
++ * GC.auto_compact = flag
++ *
++ * Updates automatic compaction mode.
++ *
++ * When enabled, the compactor will execute on every major collection.
++ *
++ * Enabling compaction will degrade performance on major collections.
++ */
+ static VALUE
+-gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v)
++gc_set_auto_compact(VALUE _, VALUE v)
+ {
+ /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for
+ * the read barrier, so we must disable automatic compaction. */
+-#if !defined(__MINGW32__) && !defined(_WIN32)
+- if (!USE_MMAP_ALIGNED_ALLOC) {
+- rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this
platform");
+- }
+-#endif
+
+ ruby_enable_autocompact = RTEST(v);
+ return v;
+ }
++#else
++# define gc_set_auto_compact rb_f_notimplement
++#endif
+
++#if GC_COMPACTION_SUPPORTED
++/*
++ * call-seq:
++ * GC.auto_compact -> true or false
++ *
++ * Returns whether or not automatic compaction has been enabled.
++ */
+ static VALUE
+-gc_get_auto_compact(rb_execution_context_t *ec, VALUE _)
++gc_get_auto_compact(VALUE _)
+ {
+ return RBOOL(ruby_enable_autocompact);
+ }
++#else
++# define gc_get_auto_compact rb_f_notimplement
++#endif
+
+ static int
+ get_envparam_size(const char *name, size_t *default_value, size_t lower_bound)
+@@ -13599,6 +13696,11 @@ Init_GC(void)
+ rb_define_singleton_method(rb_mGC, "malloc_allocated_size",
gc_malloc_allocated_size, 0);
+ rb_define_singleton_method(rb_mGC, "malloc_allocations",
gc_malloc_allocations, 0);
+ #endif
++ rb_define_singleton_method(rb_mGC, "compact", gc_compact, 0);
++ rb_define_singleton_method(rb_mGC, "auto_compact", gc_get_auto_compact,
0);
++ rb_define_singleton_method(rb_mGC, "auto_compact=", gc_set_auto_compact,
1);
++ rb_define_singleton_method(rb_mGC, "latest_compact_info",
gc_compact_stats, 0);
++ rb_define_singleton_method(rb_mGC, "verify_compaction_references",
gc_verify_compaction_references, -1);
+
+ #if GC_DEBUG_STRESS_TO_CLASS
+ rb_define_singleton_method(rb_mGC, "add_stress_to_class",
rb_gcdebug_add_stress_to_class, -1);
+diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
+index 42ad028530..411d5eab69 100644
+--- a/test/ruby/test_gc_compact.rb
++++ b/test/ruby/test_gc_compact.rb
+@@ -9,14 +9,7 @@
+ end
+
+ class TestGCCompact < Test::Unit::TestCase
+- module SupportsCompact
+- def setup
+- skip "autocompact not supported on this platform" unless
supports_auto_compact?
+- super
+- end
+-
+- private
+-
++ module CompactionSupportInspector
+ def supports_auto_compact?
+ return true unless defined?(Etc::SC_PAGE_SIZE)
+
+@@ -30,10 +23,19 @@ def supports_auto_compact?
+ end
+ end
+
+- include SupportsCompact
++ module OmitUnlessCompactSupported
++ include CompactionSupportInspector
++
++ def setup
++ omit "autocompact not supported on this platform" unless
supports_auto_compact?
++ super
++ end
++ end
++
++ include OmitUnlessCompactSupported
+
+ class AutoCompact < Test::Unit::TestCase
+- include SupportsCompact
++ include OmitUnlessCompactSupported
+
+ def test_enable_autocompact
+ before = GC.auto_compact
+@@ -87,13 +89,39 @@ def test_implicit_compaction_does_something
+ end
+ end
+
+- def os_page_size
+- return true unless defined?(Etc::SC_PAGE_SIZE)
++ class CompactMethodsNotImplemented < Test::Unit::TestCase
++ include CompactionSupportInspector
++
++ def assert_not_implemented(method, *args)
++ omit "autocompact is supported on this platform" if
supports_auto_compact?
++
++ assert_raise(NotImplementedError) { GC.send(method, *args) }
++ refute(GC.respond_to?(method), "GC.#{method} should be defined as
rb_f_notimplement")
++ end
++
++ def test_gc_compact_not_implemented
++ assert_not_implemented(:compact)
++ end
++
++ def test_gc_auto_compact_get_not_implemented
++ assert_not_implemented(:auto_compact)
++ end
++
++ def test_gc_auto_compact_set_not_implemented
++ assert_not_implemented(:auto_compact=, true)
++ end
++
++ def test_gc_latest_compact_info_not_implemented
++ assert_not_implemented(:latest_compact_info)
++ end
++
++ def test_gc_verify_compaction_references_not_implemented
++ assert_not_implemented(:verify_compaction_references)
++ end
+ end
+
+- def setup
+- skip "autocompact not supported on this platform" unless
supports_auto_compact?
+- super
++ def os_page_size
++ return true unless defined?(Etc::SC_PAGE_SIZE)
+ end
+
+ def test_gc_compact_stats
+diff --git a/gc.rb b/gc.rb
+index 72637f3796..9265dd7b57 100644
+--- a/gc.rb
++++ b/gc.rb
+@@ -38,27 +38,6 @@ def garbage_collect full_mark: true, immediate_mark: true,
immediate_sweep: true
+ Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
+ end
+
+- # call-seq:
+- # GC.auto_compact -> true or false
+- #
+- # Returns whether or not automatic compaction has been enabled.
+- #
+- def self.auto_compact
+- Primitive.gc_get_auto_compact
+- end
+-
+- # call-seq:
+- # GC.auto_compact = flag
+- #
+- # Updates automatic compaction mode.
+- #
+- # When enabled, the compactor will execute on every major collection.
+- #
+- # Enabling compaction will degrade performance on major collections.
+- def self.auto_compact=(flag)
+- Primitive.gc_set_auto_compact(flag)
+- end
+-
+ # call-seq:
+ # GC.enable -> true or false
+ #
+@@ -210,53 +189,6 @@ def self.latest_gc_info hash_or_key = nil
+ Primitive.gc_latest_gc_info hash_or_key
+ end
+
+- # call-seq:
+- # GC.latest_compact_info -> {:considered=>{:T_CLASS=>11},
:moved=>{:T_CLASS=>11}}
+- #
+- # Returns information about object moved in the most recent GC compaction.
+- #
+- # The returned hash has two keys :considered and :moved. The hash for
+- # :considered lists the number of objects that were considered for movement
+- # by the compactor, and the :moved hash lists the number of objects that
+- # were actually moved. Some objects can't be moved (maybe they were pinned)
+- # so these numbers can be used to calculate compaction efficiency.
+- def self.latest_compact_info
+- Primitive.gc_compact_stats
+- end
+-
+- # call-seq:
+- # GC.compact
+- #
+- # This function compacts objects together in Ruby's heap. It eliminates
+- # unused space (or fragmentation) in the heap by moving objects in to that
+- # unused space. This function returns a hash which contains statistics about
+- # which objects were moved. See `GC.latest_gc_info` for details about
+- # compaction statistics.
+- #
+- # This method is implementation specific and not expected to be implemented
+- # in any implementation besides MRI.
+- def self.compact
+- Primitive.gc_compact
+- end
+-
+- # call-seq:
+- # GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
+- #
+- # Verify compaction reference consistency.
+- #
+- # This method is implementation specific. During compaction, objects that
+- # were moved are replaced with T_MOVED objects. No object should have a
+- # reference to a T_MOVED object after compaction.
+- #
+- # This function doubles the heap to ensure room to move all objects,
+- # compacts the heap to make sure everything moves, updates all references,
+- # then performs a full GC. If any object contains a reference to a T_MOVED
+- # object, that object should be pushed on the mark stack, and will
+- # make a SEGV.
+- def self.verify_compaction_references(toward: nil, double_heap: false)
+- Primitive.gc_verify_compaction_references(double_heap, toward == :empty)
+- end
+-
+ # call-seq:
+ # GC.using_rvargc? -> true or false
+ #
diff --git a/ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
b/ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
new file mode 100644
index 0000000..240cc9c
--- /dev/null
+++ b/ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
@@ -0,0 +1,502 @@
+--- ruby-3.1.2/gc.rbinc 2022-04-12 13:11:17.000000000 +0200
++++ ruby/gc.rbinc 2022-06-08 12:49:16.288024971 +0200
+@@ -9,27 +9,27 @@
+ #include "builtin.h" /* for RB_BUILTIN_FUNCTION */
+ struct rb_execution_context_struct; /* in vm_core.h */
+
+-static VALUE builtin_inline_class_277(struct rb_execution_context_struct *ec, const
VALUE self)
++static VALUE builtin_inline_class_209(struct rb_execution_context_struct *ec, const
VALUE self)
+ {
+ MAYBE_UNUSED(const VALUE) flag = rb_vm_lvar(ec, -3);
+-#line 277 "gc.rb"
++#line 209 "gc.rb"
+
+ rb_objspace.flags.measure_gc = RTEST(flag) ? TRUE : FALSE;
+ return flag;
+ #line 20 "gc.rbinc"
+ }
+
+-static VALUE builtin_inline_class_289(struct rb_execution_context_struct *ec, const
VALUE self)
++static VALUE builtin_inline_class_221(struct rb_execution_context_struct *ec, const
VALUE self)
+ {
+-#line 289 "gc.rb"
++#line 221 "gc.rb"
+ return
+ RBOOL(rb_objspace.flags.measure_gc);
+ #line 28 "gc.rbinc"
+ }
+
+-static VALUE builtin_inline_class_299(struct rb_execution_context_struct *ec, const
VALUE self)
++static VALUE builtin_inline_class_231(struct rb_execution_context_struct *ec, const
VALUE self)
+ {
+-#line 299 "gc.rb"
++#line 231 "gc.rb"
+ return
+ ULL2NUM(rb_objspace.profile.total_time_ns);
+ #line 36 "gc.rbinc"
+@@ -52,31 +52,6 @@
+ }
+
+ static void
+-mjit_compile_invokebuiltin_for_gc_get_auto_compact(FILE *f, long index, unsigned
stack_size, bool inlinable_p)
+-{
+- fprintf(f, " VALUE self = GET_SELF();\n");
+- fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *,
VALUE);\n");
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
gc_get_auto_compact */\n", (VALUE)gc_get_auto_compact);
+- fprintf(f, " val = f(ec, self);\n");
+-}
+-
+-static void
+-mjit_compile_invokebuiltin_for_gc_set_auto_compact(FILE *f, long index, unsigned
stack_size, bool inlinable_p)
+-{
+- fprintf(f, " VALUE self = GET_SELF();\n");
+- fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *, VALUE,
VALUE);\n");
+- if (index == -1) {
+- fprintf(f, " const VALUE *argv = &stack[%d];\n", stack_size -
1);
+- }
+- else {
+- fprintf(f, " const unsigned int lnum =
GET_ISEQ()->body->local_table_size;\n");
+- fprintf(f, " const VALUE *argv = GET_EP() - lnum - VM_ENV_DATA_SIZE + 1
+ %ld;\n", index);
+- }
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
gc_set_auto_compact */\n", (VALUE)gc_set_auto_compact);
+- fprintf(f, " val = f(ec, self, argv[0]);\n");
+-}
+-
+-static void
+ mjit_compile_invokebuiltin_for_gc_enable(FILE *f, long index, unsigned stack_size, bool
inlinable_p)
+ {
+ fprintf(f, " VALUE self = GET_SELF();\n");
+@@ -161,40 +136,6 @@
+ }
+
+ static void
+-mjit_compile_invokebuiltin_for_gc_compact_stats(FILE *f, long index, unsigned
stack_size, bool inlinable_p)
+-{
+- fprintf(f, " VALUE self = GET_SELF();\n");
+- fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *,
VALUE);\n");
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* == gc_compact_stats
*/\n", (VALUE)gc_compact_stats);
+- fprintf(f, " val = f(ec, self);\n");
+-}
+-
+-static void
+-mjit_compile_invokebuiltin_for_gc_compact(FILE *f, long index, unsigned stack_size, bool
inlinable_p)
+-{
+- fprintf(f, " VALUE self = GET_SELF();\n");
+- fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *,
VALUE);\n");
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* == gc_compact
*/\n", (VALUE)gc_compact);
+- fprintf(f, " val = f(ec, self);\n");
+-}
+-
+-static void
+-mjit_compile_invokebuiltin_for_gc_verify_compaction_references(FILE *f, long index,
unsigned stack_size, bool inlinable_p)
+-{
+- fprintf(f, " VALUE self = GET_SELF();\n");
+- fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *, VALUE, VALUE,
VALUE);\n");
+- if (index == -1) {
+- fprintf(f, " const VALUE *argv = &stack[%d];\n", stack_size -
2);
+- }
+- else {
+- fprintf(f, " const unsigned int lnum =
GET_ISEQ()->body->local_table_size;\n");
+- fprintf(f, " const VALUE *argv = GET_EP() - lnum - VM_ENV_DATA_SIZE + 1
+ %ld;\n", index);
+- }
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
gc_verify_compaction_references */\n", (VALUE)gc_verify_compaction_references);
+- fprintf(f, " val = f(ec, self, argv[0], argv[1]);\n");
+-}
+-
+-static void
+ mjit_compile_invokebuiltin_for__bi0(FILE *f, long index, unsigned stack_size, bool
inlinable_p)
+ {
+ fprintf(f, " VALUE self = GET_SELF();\n");
+@@ -202,7 +143,7 @@
+ if (inlinable_p) {
+ fprintf(f, "%s", " {\n");
+ fprintf(f, "%s", " MAYBE_UNUSED(const VALUE) flag =
rb_vm_lvar(ec, -3);\n");
+- fprintf(f, "%s", "#line 277 \"gc.rb\"\n");
++ fprintf(f, "%s", "#line 209 \"gc.rb\"\n");
+ fprintf(f, "%s", " \n");
+ fprintf(f, "%s", " rb_objspace.flags.measure_gc =
RTEST(flag) ? TRUE : FALSE;\n");
+ fprintf(f, "%s", " return flag;\n");
+@@ -211,7 +152,7 @@
+ fprintf(f, "%s", " \n");
+ return;
+ }
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
builtin_inline_class_277 */\n", (VALUE)builtin_inline_class_277);
++ fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
builtin_inline_class_209 */\n", (VALUE)builtin_inline_class_209);
+ fprintf(f, " val = f(ec, self);\n");
+ }
+
+@@ -222,7 +163,7 @@
+ fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *,
VALUE);\n");
+ if (inlinable_p) {
+ fprintf(f, "%s", " {\n");
+- fprintf(f, "%s", "#line 289 \"gc.rb\"\n");
++ fprintf(f, "%s", "#line 221 \"gc.rb\"\n");
+ fprintf(f, "%s", " return \n");
+ fprintf(f, "%s", "
RBOOL(rb_objspace.flags.measure_gc);\n");
+ fprintf(f, "%s", "#line 52 \"gc.rbinc\"\n");
+@@ -230,7 +171,7 @@
+ fprintf(f, "%s", " \n");
+ return;
+ }
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
builtin_inline_class_289 */\n", (VALUE)builtin_inline_class_289);
++ fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
builtin_inline_class_221 */\n", (VALUE)builtin_inline_class_221);
+ fprintf(f, " val = f(ec, self);\n");
+ }
+
+@@ -241,7 +182,7 @@
+ fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *,
VALUE);\n");
+ if (inlinable_p) {
+ fprintf(f, "%s", " {\n");
+- fprintf(f, "%s", "#line 299 \"gc.rb\"\n");
++ fprintf(f, "%s", "#line 231 \"gc.rb\"\n");
+ fprintf(f, "%s", " return \n");
+ fprintf(f, "%s", "
ULL2NUM(rb_objspace.profile.total_time_ns);\n");
+ fprintf(f, "%s", "#line 59 \"gc.rbinc\"\n");
+@@ -249,7 +190,7 @@
+ fprintf(f, "%s", " \n");
+ return;
+ }
+- fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
builtin_inline_class_299 */\n", (VALUE)builtin_inline_class_299);
++ fprintf(f, " func f = (func)%"PRIuVALUE"; /* ==
builtin_inline_class_231 */\n", (VALUE)builtin_inline_class_231);
+ fprintf(f, " val = f(ec, self);\n");
+ }
+
+@@ -258,21 +199,16 @@
+ // table definition
+ static const struct rb_builtin_function gc_table[] = {
+ RB_BUILTIN_FUNCTION(0, gc_start_internal, gc_start_internal, 4,
mjit_compile_invokebuiltin_for_gc_start_internal),
+- RB_BUILTIN_FUNCTION(1, gc_get_auto_compact, gc_get_auto_compact, 0,
mjit_compile_invokebuiltin_for_gc_get_auto_compact),
+- RB_BUILTIN_FUNCTION(2, gc_set_auto_compact, gc_set_auto_compact, 1,
mjit_compile_invokebuiltin_for_gc_set_auto_compact),
+- RB_BUILTIN_FUNCTION(3, gc_enable, gc_enable, 0,
mjit_compile_invokebuiltin_for_gc_enable),
+- RB_BUILTIN_FUNCTION(4, gc_disable, gc_disable, 0,
mjit_compile_invokebuiltin_for_gc_disable),
+- RB_BUILTIN_FUNCTION(5, gc_stress_get, gc_stress_get, 0,
mjit_compile_invokebuiltin_for_gc_stress_get),
+- RB_BUILTIN_FUNCTION(6, gc_stress_set_m, gc_stress_set_m, 1,
mjit_compile_invokebuiltin_for_gc_stress_set_m),
+- RB_BUILTIN_FUNCTION(7, gc_count, gc_count, 0,
mjit_compile_invokebuiltin_for_gc_count),
+- RB_BUILTIN_FUNCTION(8, gc_stat, gc_stat, 1,
mjit_compile_invokebuiltin_for_gc_stat),
+- RB_BUILTIN_FUNCTION(9, gc_latest_gc_info, gc_latest_gc_info, 1,
mjit_compile_invokebuiltin_for_gc_latest_gc_info),
+- RB_BUILTIN_FUNCTION(10, gc_compact_stats, gc_compact_stats, 0,
mjit_compile_invokebuiltin_for_gc_compact_stats),
+- RB_BUILTIN_FUNCTION(11, gc_compact, gc_compact, 0,
mjit_compile_invokebuiltin_for_gc_compact),
+- RB_BUILTIN_FUNCTION(12, gc_verify_compaction_references,
gc_verify_compaction_references, 2,
mjit_compile_invokebuiltin_for_gc_verify_compaction_references),
+- RB_BUILTIN_FUNCTION(13, _bi0, builtin_inline_class_277, 0,
mjit_compile_invokebuiltin_for__bi0),
+- RB_BUILTIN_FUNCTION(14, _bi1, builtin_inline_class_289, 0,
mjit_compile_invokebuiltin_for__bi1),
+- RB_BUILTIN_FUNCTION(15, _bi2, builtin_inline_class_299, 0,
mjit_compile_invokebuiltin_for__bi2),
++ RB_BUILTIN_FUNCTION(1, gc_enable, gc_enable, 0,
mjit_compile_invokebuiltin_for_gc_enable),
++ RB_BUILTIN_FUNCTION(2, gc_disable, gc_disable, 0,
mjit_compile_invokebuiltin_for_gc_disable),
++ RB_BUILTIN_FUNCTION(3, gc_stress_get, gc_stress_get, 0,
mjit_compile_invokebuiltin_for_gc_stress_get),
++ RB_BUILTIN_FUNCTION(4, gc_stress_set_m, gc_stress_set_m, 1,
mjit_compile_invokebuiltin_for_gc_stress_set_m),
++ RB_BUILTIN_FUNCTION(5, gc_count, gc_count, 0,
mjit_compile_invokebuiltin_for_gc_count),
++ RB_BUILTIN_FUNCTION(6, gc_stat, gc_stat, 1,
mjit_compile_invokebuiltin_for_gc_stat),
++ RB_BUILTIN_FUNCTION(7, gc_latest_gc_info, gc_latest_gc_info, 1,
mjit_compile_invokebuiltin_for_gc_latest_gc_info),
++ RB_BUILTIN_FUNCTION(8, _bi0, builtin_inline_class_209, 0,
mjit_compile_invokebuiltin_for__bi0),
++ RB_BUILTIN_FUNCTION(9, _bi1, builtin_inline_class_221, 0,
mjit_compile_invokebuiltin_for__bi1),
++ RB_BUILTIN_FUNCTION(10, _bi2, builtin_inline_class_231, 0,
mjit_compile_invokebuiltin_for__bi2),
+ RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0, 0),
+ };
+
+@@ -282,8 +218,6 @@
+ COMPILER_WARNING_ERROR(-Wincompatible-pointer-types)
+ #endif
+ if (0) rb_builtin_function_check_arity4(gc_start_internal);
+- if (0) rb_builtin_function_check_arity0(gc_get_auto_compact);
+- if (0) rb_builtin_function_check_arity1(gc_set_auto_compact);
+ if (0) rb_builtin_function_check_arity0(gc_enable);
+ if (0) rb_builtin_function_check_arity0(gc_disable);
+ if (0) rb_builtin_function_check_arity0(gc_stress_get);
+@@ -291,12 +225,9 @@
+ if (0) rb_builtin_function_check_arity0(gc_count);
+ if (0) rb_builtin_function_check_arity1(gc_stat);
+ if (0) rb_builtin_function_check_arity1(gc_latest_gc_info);
+- if (0) rb_builtin_function_check_arity0(gc_compact_stats);
+- if (0) rb_builtin_function_check_arity0(gc_compact);
+- if (0) rb_builtin_function_check_arity2(gc_verify_compaction_references);
+- if (0) rb_builtin_function_check_arity0(builtin_inline_class_277);
+- if (0) rb_builtin_function_check_arity0(builtin_inline_class_289);
+- if (0) rb_builtin_function_check_arity0(builtin_inline_class_299);
++ if (0) rb_builtin_function_check_arity0(builtin_inline_class_209);
++ if (0) rb_builtin_function_check_arity0(builtin_inline_class_221);
++ if (0) rb_builtin_function_check_arity0(builtin_inline_class_231);
+ COMPILER_WARNING_POP
+
+ // load
+--- ruby-3.1.2/miniprelude.c 2022-04-12 13:11:17.000000000 +0200
++++ ruby/miniprelude.c 2022-06-08 12:49:16.377024871 +0200
+@@ -545,11 +545,10 @@
+
+ static const char prelude_name2[] = "<internal:gc>";
+ static const struct {
+- char L0[479]; /* 1..58 */
+- char L58[508]; /* 59..204 */
+- char L204[504]; /* 205..275 */
+- char L275[490]; /* 276..306 */
+- char L306[128]; /* 307..312 */
++ char L0[492]; /* 1..70 */
++ char L70[468]; /* 71..197 */
++ char L197[470]; /* 198..237 */
++ char L237[211]; /* 238..244 */
+ } prelude_code2 = {
+ #line 1 "gc.rb"
+ ""/* for gc.c */
+@@ -593,29 +592,6 @@
+ " end\n"
+ "\n"
+ "\n"/* call-seq: */
+-"\n"/* GC.auto_compact -> true or false */
+-"\n"/* */
+-"\n"/* Returns whether or not automatic compaction has been enabled. */
+-"\n"/* */
+-" def self.auto_compact\n"
+-" Primitive.gc_get_auto_compact\n"
+-" end\n"
+-"\n"
+-"\n"/* call-seq: */
+-"\n"/* GC.auto_compact = flag */
+-"\n"/* */
+-"\n"/* Updates automatic compaction mode. */
+-"\n"/* */
+-"\n"/* When enabled, the compactor will execute on every major collection.
*/
+-"\n"/* */
+-"\n"/* Enabling compaction will degrade performance on major collections. */
+-" def self.auto_compact=(flag)\n"
+-,
+-#line 59 "gc.rb"
+-" Primitive.gc_set_auto_compact(flag)\n"
+-" end\n"
+-"\n"
+-"\n"/* call-seq: */
+ "\n"/* GC.enable -> true or false */
+ "\n"/* */
+ "\n"/* Enables garbage collection, returning +true+ if garbage */
+@@ -645,6 +621,8 @@
+ "\n"/* GC.stress -> integer, true or false */
+ "\n"/* */
+ "\n"/* Returns current status of GC stress mode. */
++,
++#line 71 "gc.rb"
+ " def self.stress\n"
+ " Primitive.gc_stress_get\n"
+ " end\n"
+@@ -758,8 +736,6 @@
+ "\n"/* GC.latest_gc_info(:major_by) -> :malloc */
+ "\n"/* */
+ "\n"/* Returns information about the most recent garbage collection. */
+-,
+-#line 205 "gc.rb"
+ "\n"/* */
+ "\n"/* If the optional argument, hash, is given, */
+ "\n"/* it is overwritten and returned. */
+@@ -768,59 +744,14 @@
+ " Primitive.gc_latest_gc_info hash_or_key\n"
+ " end\n"
+ "\n"
+-"\n"/* call-seq: */
+-"\n"/* GC.latest_compact_info -> {:considered=>{:T_CLASS=>11},
:moved=>{:T_CLASS=>11}} */
+-"\n"/* */
+-"\n"/* Returns information about object moved in the most recent GC
compaction. */
+-"\n"/* */
+-"\n"/* The returned hash has two keys :considered and :moved. The hash for
*/
+-"\n"/* :considered lists the number of objects that were considered for
movement */
+-"\n"/* by the compactor, and the :moved hash lists the number of objects that
*/
+-"\n"/* were actually moved. Some objects can't be moved (maybe they were
pinned) */
+-"\n"/* so these numbers can be used to calculate compaction efficiency. */
+-" def self.latest_compact_info\n"
+-" Primitive.gc_compact_stats\n"
+-" end\n"
+-"\n"
+-"\n"/* call-seq: */
+-"\n"/* GC.compact */
+-"\n"/* */
+-"\n"/* This function compacts objects together in Ruby's heap. It
eliminates */
+-"\n"/* unused space (or fragmentation) in the heap by moving objects in to
that */
+-"\n"/* unused space. This function returns a hash which contains statistics
about */
+-"\n"/* which objects were moved. See `GC.latest_gc_info` for details about
*/
+-"\n"/* compaction statistics. */
+-"\n"/* */
+-"\n"/* This method is implementation specific and not expected to be
implemented */
+-"\n"/* in any implementation besides MRI. */
+-" def self.compact\n"
+-" Primitive.gc_compact\n"
+-" end\n"
+-"\n"
+-"\n"/* call-seq: */
+-"\n"/* GC.verify_compaction_references(toward: nil, double_heap: false)
-> hash */
+-"\n"/* */
+-"\n"/* Verify compaction reference consistency. */
+-"\n"/* */
+-"\n"/* This method is implementation specific. During compaction, objects
that */
+-"\n"/* were moved are replaced with T_MOVED objects. No object should have a
*/
+-"\n"/* reference to a T_MOVED object after compaction. */
+-"\n"/* */
+-"\n"/* This function doubles the heap to ensure room to move all objects, */
+-"\n"/* compacts the heap to make sure everything moves, updates all
references, */
+-"\n"/* then performs a full GC. If any object contains a reference to a
T_MOVED */
+-"\n"/* object, that object should be pushed on the mark stack, and will */
+-"\n"/* make a SEGV. */
+-" def self.verify_compaction_references(toward: nil, double_heap: false)\n"
+-" Primitive.gc_verify_compaction_references(double_heap, toward ==
:empty)\n"
+-" end\n"
+-"\n"
+ "\n"/* call-seq: */
+ "\n"/* GC.using_rvargc? -> true or false */
+ "\n"/* */
+ "\n"/* Returns true if using experimental feature Variable Width Allocation,
false */
+ "\n"/* otherwise. */
+ " def self.using_rvargc?\n"/* :nodoc: */
++,
++#line 198 "gc.rb"
+ " GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] > 1\n"
+ " end\n"
+ "\n"
+@@ -831,8 +762,6 @@
+ "\n"/* Enable to measure GC time. */
+ "\n"/* You can get the result with <tt>GC.stat(:time)</tt>. */
+ "\n"/* Note that GC time measurement can cause some performance overhead. */
+-,
+-#line 276 "gc.rb"
+ " def self.measure_total_time=(flag)\n"
+ " Primitive.cstmt! %{\n"
+ " rb_objspace.flags.measure_gc = RTEST(flag) ? TRUE : FALSE;\n"
+@@ -863,15 +792,15 @@
+ "end\n"
+ "\n"
+ "module ObjectSpace\n"
+-" def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep:
true\n"
+ ,
+-#line 307 "gc.rb"
++#line 238 "gc.rb"
++" def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep:
true\n"
+ " Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep,
false\n"
+ " end\n"
+ "\n"
+ " module_function :garbage_collect\n"
+ "end\n"
+-#line 875 "miniprelude.c"
++#line 804 "miniprelude.c"
+ };
+
+ static const char prelude_name3[] = "<internal:numeric>";
+@@ -1223,7 +1152,7 @@
+ " end\n"
+ "\n"
+ "end\n"
+-#line 1227 "miniprelude.c"
++#line 1156 "miniprelude.c"
+ };
+
+ static const char prelude_name4[] = "<internal:io>";
+@@ -1354,7 +1283,7 @@
+ " Primitive.io_write_nonblock(buf, exception)\n"
+ " end\n"
+ "end\n"
+-#line 1358 "miniprelude.c"
++#line 1287 "miniprelude.c"
+ };
+
+ static const char prelude_name5[] = "<internal:marshal>";
+@@ -1402,7 +1331,7 @@
+ " alias restore load\n"
+ " end\n"
+ "end\n"
+-#line 1406 "miniprelude.c"
++#line 1335 "miniprelude.c"
+ };
+
+ static const char prelude_name6[] = "<internal:pack>";
+@@ -1724,7 +1653,7 @@
+ " Primitive.pack_unpack1(fmt, offset)\n"
+ " end\n"
+ "end\n"
+-#line 1728 "miniprelude.c"
++#line 1657 "miniprelude.c"
+ };
+
+ static const char prelude_name7[] = "<internal:trace_point>";
+@@ -2111,7 +2040,7 @@
+ " Primitive.tracepoint_attr_instruction_sequence\n"
+ " end\n"
+ "end\n"
+-#line 2115 "miniprelude.c"
++#line 2044 "miniprelude.c"
+ };
+
+ static const char prelude_name8[] = "<internal:warning>";
+@@ -2172,7 +2101,7 @@
+ " Primitive.rb_warn_m(msgs, uplevel, category)\n"
+ " end\n"
+ "end\n"
+-#line 2176 "miniprelude.c"
++#line 2105 "miniprelude.c"
+ };
+
+ static const char prelude_name9[] = "<internal:array>";
+@@ -2249,7 +2178,7 @@
+ " end\n"
+ " end\n"
+ "end\n"
+-#line 2253 "miniprelude.c"
++#line 2182 "miniprelude.c"
+ };
+
+ static const char prelude_name10[] = "<internal:kernel>";
+@@ -2438,7 +2367,7 @@
+ " end\n"
+ " end\n"
+ "end\n"
+-#line 2442 "miniprelude.c"
++#line 2371 "miniprelude.c"
+ };
+
+ static const char prelude_name11[] = "<internal:ractor>";
+@@ -3305,7 +3234,7 @@
+ " }\n"
+ " end\n"
+ "end\n"
+-#line 3309 "miniprelude.c"
++#line 3238 "miniprelude.c"
+ };
+
+ static const char prelude_name12[] = "<internal:timev>";
+@@ -3628,7 +3557,7 @@
+ " Primitive.time_init_args(year, mon, mday, hour, min, sec, zone)\n"
+ " end\n"
+ "end\n"
+-#line 3632 "miniprelude.c"
++#line 3561 "miniprelude.c"
+ };
+
+ static const char prelude_name13[] = "<internal:nilclass>";
+@@ -3661,7 +3590,7 @@
+ " return 0.0\n"
+ " end\n"
+ "end\n"
+-#line 3665 "miniprelude.c"
++#line 3594 "miniprelude.c"
+ };
+
+ static const char prelude_name14[] = "<internal:prelude>";
+@@ -3691,7 +3620,7 @@
+ "\n"
+ " private :pp\n"
+ "end\n"
+-#line 3695 "miniprelude.c"
++#line 3624 "miniprelude.c"
+ };
+
+ static const char prelude_name15[] = "<internal:gem_prelude>";
+@@ -3718,7 +3647,7 @@
+ "rescue LoadError\n"
+ " warn \"`did_you_mean' was not loaded.\"\n"
+ "end if defined?(DidYouMean)\n"
+-#line 3722 "miniprelude.c"
++#line 3651 "miniprelude.c"
+ };
+
+ static const char prelude_name16[] = "<internal:yjit>";
+@@ -4059,7 +3988,7 @@
+ " end\n"
+ " end\n"
+ "end\n"
+-#line 4063 "miniprelude.c"
++#line 3992 "miniprelude.c"
+ };
+
+ COMPILER_WARNING_POP
diff --git a/ruby.spec b/ruby.spec
index a92223c..eb3ac14 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -22,7 +22,7 @@
%endif
-%global release 164
+%global release 165
%{!?release_string:%define release_string
%{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
# The RubyGems library has to stay out of Ruby directory tree, since the
@@ -171,6 +171,22 @@ Patch20: ruby-bundler-2.4.0-bundle-update-bundler-test-in-ruby.patch
#
https://bugs.ruby-lang.org/issues/18373
#
https://github.com/ruby/ruby/pull/5774
Patch21: ruby-3.2.0-Build-extension-libraries-in-bundled-gems.patch
+# If GC compaction is not supported on platform, define the
+# corresponding GC methods as not implemented.
+#
https://bugs.ruby-lang.org/issues/18779
+#
https://github.com/ruby/ruby/pull/5934
+Patch22: ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
+# To regenerate the patch you need to have ruby, autoconf, xz, tar and make installed:
+# tar -Jxvf ./ruby-3.1.2.tar.xz
+# git clone
https://github.com/ruby/ruby.git
+# cd ruby && git checkout v3_1_2
+# patch -p1 <
../ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
+# ./autogen.sh && ./configure
+# make gc.rbinc miniprelude.c
+# cd ..
+# diff -u {ruby-3.1.2,ruby}/gc.rbinc >
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
+# diff -u {ruby-3.1.2,ruby}/miniprelude.c >>
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
+Patch23: ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Suggests: rubypick
@@ -643,6 +659,8 @@ rm -rf ext/fiddle/libffi*
mkdir .bundle/specifications
find .bundle/gems -name '*-[0-9]*.gemspec' -exec cp -t .bundle/specifications/ {}
+
%patch21 -p1
+%patch22 -p1
+%patch23 -p1
# Provide an example of usage of the tapset:
cp -a %{SOURCE3} .
@@ -650,6 +668,12 @@ cp -a %{SOURCE3} .
%build
autoconf
+# Some platforms do not support compaction and upstream does not seem to provide the
+# right mechanism for the enablement of the preprocessor macros.
+#
https://bugs.ruby-lang.org/issues/18829
+%ifnarch ppc64le
+CFLAGS="%{build_cflags} -DGC_COMPACTION_SUPPORTED"
+%endif
%configure \
--with-rubylibprefix='%{ruby_libdir}' \
--with-archlibdir='%{_libdir}' \
@@ -1499,6 +1523,9 @@ mv test/fiddle/test_import.rb{,.disable}
%changelog
+* Tue Jun 07 2022 Jarek Prokop <jprokop(a)redhat.com> - 3.1.2-165
+- Define GC compaction methods as rb_f_notimplement on unsupported platforms.
+
* Thu Apr 14 2022 Vít Ondruch <vondruch(a)redhat.com> - 3.1.2-164
- Upgrade to Ruby 3.1.2.
- Use upstream patch for correct build of gem extensions.
commit f1f652612352c88bae7e1dc1f280483ff5b8fe41
Author: Jun Aruga <jaruga(a)redhat.com>
Date: Wed May 4 20:09:28 2022 +0200
Update a comment about `make` verbose option, dropping `Q=` explanation.
According to the <
https://bugs.ruby-lang.org/issues/18756>, the `Q=` is not
recommended. The `V=1` is recommended to output for the verbose mode.
The `make V=1` suppresses some logs that `make` without `V=1` outputs rather
than just adding verbose logs.
While the `V=1 ECHO0=echo` is more equivalent with `Q=`, the
`make V=1 ECHO0=echo` doesn't really output meaningful logs additionally.
So, the `make V=1` is the best option for us to check the compiler flags.
diff --git a/ruby.spec b/ruby.spec
index a194ec2..a92223c 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -670,8 +670,8 @@ autoconf
--with-ruby-version='' \
--enable-multiarch \
-# Q= makes the build output more verbose and allows to check Fedora
-# compiler options.
+# V=1 in %%make_build outputs the compiler options more verbosely.
+#
https://bugs.ruby-lang.org/issues/18756
%make_build COPY="cp -p"
%install
commit cf59e2c5f7c8f5a3ece232c115f9dcfd646fa7fd
Author: Jun Aruga <jaruga(a)redhat.com>
Date: Thu Apr 21 16:52:48 2022 +0200
Drop `Q=` in make options.
Because the `%make_build` macro includes the `V=1`. Note there is no actual
difference of build.log between before and after this commit.
```
$ rpm --eval %make_build
/usr/bin/make -O -j8 V=1 VERBOSE=1
```
diff --git a/ruby.spec b/ruby.spec
index f5d028d..a194ec2 100644
--- a/ruby.spec
+++ b/ruby.spec
@@ -672,7 +672,7 @@ autoconf
# Q= makes the build output more verbose and allows to check Fedora
# compiler options.
-%make_build COPY="cp -p" Q=
+%make_build COPY="cp -p"
%install
rm -rf %{buildroot}