<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/gc/mmtk, branch v4.0.4</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>[ruby/mmtk] Implement Ruby heap</title>
<updated>2025-12-22T21:54:27+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-22T16:24:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=af30e4714ccb0dabff85298ee2305d84103b98d1'/>
<id>af30e4714ccb0dabff85298ee2305d84103b98d1</id>
<content type='text'>
This heap emulates the growth characteristics of the Ruby default GC's
heap. By default, the heap grows by 40%, requires at least 20% empty
after a GC, and allows at most 65% empty before it shrinks the heap. This
is all configurable via the same environment variables the default GC
uses (`RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO`, `RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO`,
`RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO`, respectively).

The Ruby heap can be enabled via the `MMTK_HEAP_MODE=ruby` environment
variable.

Compared to the dynamic heap in MMTk (which uses the MemBalancer algorithm),
the Ruby heap allows the heap to grow more generously, which uses a bit
more memory but offers significant performance gains because it runs GC
much less frequently.

We can see in the benchmarks below that this Ruby heap heap gives faster
performance than the dynamic heap in every benchmark, with over 2x faster
in many of them. We see that memory is often around 10-20% higher with
certain outliers that use significantly more memory like hexapdf and
erubi-rails. We can also see that this brings MMTk's Ruby heap much
closer in performance to the default GC.

Ruby heap benchmark results:

    --------------  --------------  ----------  ---------
    bench           ruby heap (ms)  stddev (%)  RSS (MiB)
    activerecord    233.6           10.7        85.9
    chunky-png      457.1           1.1         79.3
    erubi-rails     1148.0          3.8         133.3
    hexapdf         1570.5          2.4         403.0
    liquid-c        42.8            5.3         43.4
    liquid-compile  41.3            7.6         52.6
    liquid-render   102.8           3.8         55.3
    lobsters        651.9           8.0         426.3
    mail            106.4           1.8         67.2
    psych-load      1552.1          0.8         43.4
    railsbench      1707.2          6.0         145.6
    rubocop         127.2           15.3        148.8
    ruby-lsp        136.6           11.7        113.7
    sequel          47.2            5.9         44.4
    shipit          1197.5          3.6         301.0
    --------------  --------------  ----------  ---------

Dynamic heap benchmark results:

    --------------  -----------------  ----------  ---------
    bench           dynamic heap (ms)  stddev (%)  RSS (MiB)
    activerecord    845.3              3.1         76.7
    chunky-png      525.9              0.4         38.9
    erubi-rails     2694.9             3.4         115.8
    hexapdf         2344.8             5.6         164.9
    liquid-c        73.7               5.0         40.5
    liquid-compile  107.1              6.8         40.3
    liquid-render   147.2              1.7         39.5
    lobsters        697.6              4.5         342.0
    mail            224.6              2.1         64.0
    psych-load      4326.7             0.6         37.4
    railsbench      3218.0             5.5         124.7
    rubocop         203.6              6.1         110.9
    ruby-lsp        350.7              3.2         79.0
    sequel          121.8              2.5         39.6
    shipit          1510.1             3.1         220.8
    --------------  -----------------  ----------  ---------

Default GC benchmark results:

    --------------  ---------------  ----------  ---------
    bench           default GC (ms)  stddev (%)  RSS (MiB)
    activerecord    148.4            0.6         67.9
    chunky-png      440.2            0.7         57.0
    erubi-rails     722.7            0.3         97.8
    hexapdf         1466.2           1.7         254.3
    liquid-c        32.5             3.6         42.3
    liquid-compile  31.2             1.9         35.4
    liquid-render   88.3             0.7         30.8
    lobsters        633.6            7.0         305.4
    mail            76.6             1.6         53.2
    psych-load      1166.2           1.3         29.1
    railsbench      1262.9           2.3         114.7
    rubocop         105.6            0.8         95.4
    ruby-lsp        101.6            1.4         75.4
    sequel          27.4             1.2         33.1
    shipit          1083.1           1.5         163.4
    --------------  ---------------  ----------  ---------

https://github.com/ruby/mmtk/commit/c0ca29922d
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This heap emulates the growth characteristics of the Ruby default GC's
heap. By default, the heap grows by 40%, requires at least 20% empty
after a GC, and allows at most 65% empty before it shrinks the heap. This
is all configurable via the same environment variables the default GC
uses (`RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO`, `RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO`,
`RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO`, respectively).

The Ruby heap can be enabled via the `MMTK_HEAP_MODE=ruby` environment
variable.

Compared to the dynamic heap in MMTk (which uses the MemBalancer algorithm),
the Ruby heap allows the heap to grow more generously, which uses a bit
more memory but offers significant performance gains because it runs GC
much less frequently.

We can see in the benchmarks below that this Ruby heap heap gives faster
performance than the dynamic heap in every benchmark, with over 2x faster
in many of them. We see that memory is often around 10-20% higher with
certain outliers that use significantly more memory like hexapdf and
erubi-rails. We can also see that this brings MMTk's Ruby heap much
closer in performance to the default GC.

Ruby heap benchmark results:

    --------------  --------------  ----------  ---------
    bench           ruby heap (ms)  stddev (%)  RSS (MiB)
    activerecord    233.6           10.7        85.9
    chunky-png      457.1           1.1         79.3
    erubi-rails     1148.0          3.8         133.3
    hexapdf         1570.5          2.4         403.0
    liquid-c        42.8            5.3         43.4
    liquid-compile  41.3            7.6         52.6
    liquid-render   102.8           3.8         55.3
    lobsters        651.9           8.0         426.3
    mail            106.4           1.8         67.2
    psych-load      1552.1          0.8         43.4
    railsbench      1707.2          6.0         145.6
    rubocop         127.2           15.3        148.8
    ruby-lsp        136.6           11.7        113.7
    sequel          47.2            5.9         44.4
    shipit          1197.5          3.6         301.0
    --------------  --------------  ----------  ---------

Dynamic heap benchmark results:

    --------------  -----------------  ----------  ---------
    bench           dynamic heap (ms)  stddev (%)  RSS (MiB)
    activerecord    845.3              3.1         76.7
    chunky-png      525.9              0.4         38.9
    erubi-rails     2694.9             3.4         115.8
    hexapdf         2344.8             5.6         164.9
    liquid-c        73.7               5.0         40.5
    liquid-compile  107.1              6.8         40.3
    liquid-render   147.2              1.7         39.5
    lobsters        697.6              4.5         342.0
    mail            224.6              2.1         64.0
    psych-load      4326.7             0.6         37.4
    railsbench      3218.0             5.5         124.7
    rubocop         203.6              6.1         110.9
    ruby-lsp        350.7              3.2         79.0
    sequel          121.8              2.5         39.6
    shipit          1510.1             3.1         220.8
    --------------  -----------------  ----------  ---------

Default GC benchmark results:

    --------------  ---------------  ----------  ---------
    bench           default GC (ms)  stddev (%)  RSS (MiB)
    activerecord    148.4            0.6         67.9
    chunky-png      440.2            0.7         57.0
    erubi-rails     722.7            0.3         97.8
    hexapdf         1466.2           1.7         254.3
    liquid-c        32.5             3.6         42.3
    liquid-compile  31.2             1.9         35.4
    liquid-render   88.3             0.7         30.8
    lobsters        633.6            7.0         305.4
    mail            76.6             1.6         53.2
    psych-load      1166.2           1.3         29.1
    railsbench      1262.9           2.3         114.7
    rubocop         105.6            0.8         95.4
    ruby-lsp        101.6            1.4         75.4
    sequel          27.4             1.2         33.1
    shipit          1083.1           1.5         163.4
    --------------  ---------------  ----------  ---------

https://github.com/ruby/mmtk/commit/c0ca29922d
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Add a 32 byte heap for allocating smaller objects</title>
<updated>2025-12-21T13:59:28+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-20T16:42:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=37b98f0df71e85a831677562dc08f6ce6cdae842'/>
<id>37b98f0df71e85a831677562dc08f6ce6cdae842</id>
<content type='text'>
https://github.com/ruby/mmtk/commit/c4cca6c1c3
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/mmtk/commit/c4cca6c1c3
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Implement fast path for bump pointer allocator</title>
<updated>2025-12-21T02:55:12+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-20T21:08:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=038b158fa30d1b1cda153aeb10dac5f59f966036'/>
<id>038b158fa30d1b1cda153aeb10dac5f59f966036</id>
<content type='text'>
Adding a fast path for bump pointer allocator can improve allocation
performance.

For the following microbenchmark with MMTK_HEAP_MIN=100MiB:

    10_000_000.times { String.new }

Before:

    810.7 ms ±   8.3 ms    [User: 790.9 ms, System: 40.3 ms]

After:

    777.9 ms ±  10.4 ms    [User: 759.0 ms, System: 37.9 ms]

https://github.com/ruby/mmtk/commit/0ff5c9f579
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Adding a fast path for bump pointer allocator can improve allocation
performance.

For the following microbenchmark with MMTK_HEAP_MIN=100MiB:

    10_000_000.times { String.new }

Before:

    810.7 ms ±   8.3 ms    [User: 790.9 ms, System: 40.3 ms]

After:

    777.9 ms ±  10.4 ms    [User: 759.0 ms, System: 37.9 ms]

https://github.com/ruby/mmtk/commit/0ff5c9f579
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Make rb_gc_impl_heap_id_for_size use MMTK_HEAP_COUNT</title>
<updated>2025-12-20T16:41:11+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-20T16:39:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6d5605b28a800be19357ec57ff6c8e1118aabca0'/>
<id>6d5605b28a800be19357ec57ff6c8e1118aabca0</id>
<content type='text'>
https://github.com/ruby/mmtk/commit/2185189df4
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/mmtk/commit/2185189df4
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Call rb_bug when Ruby mutator thread panics</title>
<updated>2025-12-20T13:40:00+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-19T22:16:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6bf921051ceba1742318e3c92dddd50ba4f05d17'/>
<id>6bf921051ceba1742318e3c92dddd50ba4f05d17</id>
<content type='text'>
This will allow the Ruby backtrace, memory mapping, etc. to be outputted
when a Ruby mutator thread panics.

https://github.com/ruby/mmtk/commit/d10fd325dd
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This will allow the Ruby backtrace, memory mapping, etc. to be outputted
when a Ruby mutator thread panics.

https://github.com/ruby/mmtk/commit/d10fd325dd
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Extract max object size to MMTK_MAX_OBJ_SIZE</title>
<updated>2025-12-19T22:14:02+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-19T01:01:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8274c5e1428b5b88e885857d466822cbadc19761'/>
<id>8274c5e1428b5b88e885857d466822cbadc19761</id>
<content type='text'>
https://github.com/ruby/mmtk/commit/ed9036c295
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/mmtk/commit/ed9036c295
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Extract heap count to MMTK_HEAP_COUNT macro</title>
<updated>2025-12-19T22:13:49+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-19T01:00:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ed0fae5b501dea14617103ab5ec2d042f445ed7f'/>
<id>ed0fae5b501dea14617103ab5ec2d042f445ed7f</id>
<content type='text'>
https://github.com/ruby/mmtk/commit/4e789e118b
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/ruby/mmtk/commit/4e789e118b
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "gc.c: Pass shape_id to `newobj_init`"</title>
<updated>2025-12-05T23:40:39+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-12-05T22:08:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=791acc5697afc8f256e652169f7c85a3d90b3f06'/>
<id>791acc5697afc8f256e652169f7c85a3d90b3f06</id>
<content type='text'>
This reverts commit 228d13f6ed914d1e7f6bd2416e3f5be8283be865.

This commit makes default.c and mmtk.c depend on shape.h, which prevents
them from building independently.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 228d13f6ed914d1e7f6bd2416e3f5be8283be865.

This commit makes default.c and mmtk.c depend on shape.h, which prevents
them from building independently.
</pre>
</div>
</content>
</entry>
<entry>
<title>gc.c: Pass shape_id to `newobj_init`</title>
<updated>2025-12-03T18:51:48+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-12-03T17:08:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=228d13f6ed914d1e7f6bd2416e3f5be8283be865'/>
<id>228d13f6ed914d1e7f6bd2416e3f5be8283be865</id>
<content type='text'>
Attempt to fix the following SEGV:

```
ruby(gc_mark) ../src/gc/default/default.c:4429
ruby(gc_mark_children+0x45) [0x560b380bf8b5] ../src/gc/default/default.c:4625
ruby(gc_mark_stacked_objects) ../src/gc/default/default.c:4647
ruby(gc_mark_stacked_objects_all) ../src/gc/default/default.c:4685
ruby(gc_marks_rest) ../src/gc/default/default.c:5707
ruby(gc_marks+0x4e7) [0x560b380c41c1] ../src/gc/default/default.c:5821
ruby(gc_start) ../src/gc/default/default.c:6502
ruby(heap_prepare+0xa4) [0x560b380c4efc] ../src/gc/default/default.c:2074
ruby(heap_next_free_page) ../src/gc/default/default.c:2289
ruby(newobj_cache_miss) ../src/gc/default/default.c:2396
ruby(RB_SPECIAL_CONST_P+0x0) [0x560b380c5df4] ../src/gc/default/default.c:2420
ruby(RB_BUILTIN_TYPE) ../src/include/ruby/internal/value_type.h:184
ruby(newobj_init) ../src/gc/default/default.c:2136
ruby(rb_gc_impl_new_obj) ../src/gc/default/default.c:2500
ruby(newobj_of) ../src/gc.c:996
ruby(rb_imemo_new+0x37) [0x560b380d8bed] ../src/imemo.c:46
ruby(imemo_fields_new) ../src/imemo.c:105
ruby(rb_imemo_fields_new) ../src/imemo.c:120
```

I have no reproduction, but my understanding based on the backtrace
and error is that GC is triggered inside `newobj_init` causing the
new object to be marked while in a incomplete state.

I believe the fix is to pass the `shape_id` down to `newobj_init`
so it can be set before the GC has a chance to trigger.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Attempt to fix the following SEGV:

```
ruby(gc_mark) ../src/gc/default/default.c:4429
ruby(gc_mark_children+0x45) [0x560b380bf8b5] ../src/gc/default/default.c:4625
ruby(gc_mark_stacked_objects) ../src/gc/default/default.c:4647
ruby(gc_mark_stacked_objects_all) ../src/gc/default/default.c:4685
ruby(gc_marks_rest) ../src/gc/default/default.c:5707
ruby(gc_marks+0x4e7) [0x560b380c41c1] ../src/gc/default/default.c:5821
ruby(gc_start) ../src/gc/default/default.c:6502
ruby(heap_prepare+0xa4) [0x560b380c4efc] ../src/gc/default/default.c:2074
ruby(heap_next_free_page) ../src/gc/default/default.c:2289
ruby(newobj_cache_miss) ../src/gc/default/default.c:2396
ruby(RB_SPECIAL_CONST_P+0x0) [0x560b380c5df4] ../src/gc/default/default.c:2420
ruby(RB_BUILTIN_TYPE) ../src/include/ruby/internal/value_type.h:184
ruby(newobj_init) ../src/gc/default/default.c:2136
ruby(rb_gc_impl_new_obj) ../src/gc/default/default.c:2500
ruby(newobj_of) ../src/gc.c:996
ruby(rb_imemo_new+0x37) [0x560b380d8bed] ../src/imemo.c:46
ruby(imemo_fields_new) ../src/imemo.c:105
ruby(rb_imemo_fields_new) ../src/imemo.c:120
```

I have no reproduction, but my understanding based on the backtrace
and error is that GC is triggered inside `newobj_init` causing the
new object to be marked while in a incomplete state.

I believe the fix is to pass the `shape_id` down to `newobj_init`
so it can be set before the GC has a chance to trigger.
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/mmtk] Ensure not blocking for GC in rb_gc_impl_before_fork</title>
<updated>2025-11-19T02:08:49+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-11-18T02:39:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f040b94cf559855ab3755f6333fb2d4a8f81e0d5'/>
<id>f040b94cf559855ab3755f6333fb2d4a8f81e0d5</id>
<content type='text'>
In rb_gc_impl_before_fork, it locks the VM and barriers all the Ractors
before calling mmtk_before_fork. However, since rb_mmtk_block_for_gc is
a barrier point, one or more Ractors could be paused there. However,
mmtk_before_fork is not compatible with that because it assumes that the
MMTk workers are idle, but the workers are not idle because they are
busy working on a GC.

This commit essentially implements a trylock. It will optimistically
lock but will release the lock if it detects that any other Ractors are
waiting in rb_mmtk_block_for_gc.

For example, the following script demonstrates the issue:

    puts "Hello #{Process.pid}"

    100.times do |i|
      puts "i = #{i}"
      Ractor.new(i) do |j|
        puts "Ractor #{j} hello"
        1000.times do |i|
          s = "#{j}-#{i}"
        end
        Ractor.receive
        puts "Ractor #{j} goodbye"
      end
      pid = fork { }
      puts "Child pid is #{pid}"
      _, status = Process.waitpid2 pid
      puts status.success?
    end

    puts "Goodbye"

We can see the MMTk worker thread is waiting to start the GC:

    #4  0x00007ffff66538b1 in rb_mmtk_stop_the_world () at gc/mmtk/mmtk.c:101
    #5  0x00007ffff6d04caf in mmtk_ruby::collection::{impl#0}::stop_all_mutators&lt;mmtk::scheduler::gc_work::{impl#14}::do_work::{closure_env#0}&lt;mmtk::plan::immix::gc_work::ImmixGCWorkContext&lt;mmtk_ruby::Ruby, 0&gt;&gt;&gt; (_tls=..., mutator_visitor=...) at src/collection.rs:23

However, the mutator thread is stuck in mmtk_before_fork trying to stop
that worker thread:

    #4  0x00007ffff6c0b621 in std::sys::thread::unix::Thread::join () at library/std/src/sys/thread/unix.rs:134
    #5  0x00007ffff6658b6e in std::thread::JoinInner&lt;()&gt;::join&lt;()&gt; (self=...)
    #6  0x00007ffff6658d4c in std::thread::JoinHandle&lt;()&gt;::join&lt;()&gt; (self=...)
    #7  0x00007ffff665795e in mmtk_ruby::binding::RubyBinding::join_all_gc_threads (self=0x7ffff72462d0 &lt;mmtk_ruby::BINDING+8&gt;) at src/binding.rs:115
    #8  0x00007ffff66561a8 in mmtk_ruby::api::mmtk_before_fork () at src/api.rs:309
    #9  0x00007ffff66556ff in rb_gc_impl_before_fork (objspace_ptr=0x555555d17980) at gc/mmtk/mmtk.c:1054
    #10 0x00005555556bbc3e in rb_gc_before_fork () at gc.c:5429

https://github.com/ruby/mmtk/commit/1a629504a7
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In rb_gc_impl_before_fork, it locks the VM and barriers all the Ractors
before calling mmtk_before_fork. However, since rb_mmtk_block_for_gc is
a barrier point, one or more Ractors could be paused there. However,
mmtk_before_fork is not compatible with that because it assumes that the
MMTk workers are idle, but the workers are not idle because they are
busy working on a GC.

This commit essentially implements a trylock. It will optimistically
lock but will release the lock if it detects that any other Ractors are
waiting in rb_mmtk_block_for_gc.

For example, the following script demonstrates the issue:

    puts "Hello #{Process.pid}"

    100.times do |i|
      puts "i = #{i}"
      Ractor.new(i) do |j|
        puts "Ractor #{j} hello"
        1000.times do |i|
          s = "#{j}-#{i}"
        end
        Ractor.receive
        puts "Ractor #{j} goodbye"
      end
      pid = fork { }
      puts "Child pid is #{pid}"
      _, status = Process.waitpid2 pid
      puts status.success?
    end

    puts "Goodbye"

We can see the MMTk worker thread is waiting to start the GC:

    #4  0x00007ffff66538b1 in rb_mmtk_stop_the_world () at gc/mmtk/mmtk.c:101
    #5  0x00007ffff6d04caf in mmtk_ruby::collection::{impl#0}::stop_all_mutators&lt;mmtk::scheduler::gc_work::{impl#14}::do_work::{closure_env#0}&lt;mmtk::plan::immix::gc_work::ImmixGCWorkContext&lt;mmtk_ruby::Ruby, 0&gt;&gt;&gt; (_tls=..., mutator_visitor=...) at src/collection.rs:23

However, the mutator thread is stuck in mmtk_before_fork trying to stop
that worker thread:

    #4  0x00007ffff6c0b621 in std::sys::thread::unix::Thread::join () at library/std/src/sys/thread/unix.rs:134
    #5  0x00007ffff6658b6e in std::thread::JoinInner&lt;()&gt;::join&lt;()&gt; (self=...)
    #6  0x00007ffff6658d4c in std::thread::JoinHandle&lt;()&gt;::join&lt;()&gt; (self=...)
    #7  0x00007ffff665795e in mmtk_ruby::binding::RubyBinding::join_all_gc_threads (self=0x7ffff72462d0 &lt;mmtk_ruby::BINDING+8&gt;) at src/binding.rs:115
    #8  0x00007ffff66561a8 in mmtk_ruby::api::mmtk_before_fork () at src/api.rs:309
    #9  0x00007ffff66556ff in rb_gc_impl_before_fork (objspace_ptr=0x555555d17980) at gc/mmtk/mmtk.c:1054
    #10 0x00005555556bbc3e in rb_gc_before_fork () at gc.c:5429

https://github.com/ruby/mmtk/commit/1a629504a7
</pre>
</div>
</content>
</entry>
</feed>
