| Age | Commit message (Collapse) | Author |
|
https://github.com/ruby/mmtk/commit/031785b41c
|
|
gc/mmtk/mmtk.c:505:1: warning: function 'rb_mmtk_gc_thread_panic_handler' could be declared with attribute 'noreturn' [-Wmissing-noreturn]
505 | {
| ^
gc/mmtk/mmtk.c:987:27: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
987 | char obj_info_buf[info_size];
| ^~~~~~~~~
gc/mmtk/mmtk.c:990:34: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
990 | char parent_obj_info_buf[info_size];
| ^~~~~~~~~
https://github.com/ruby/mmtk/commit/8ce21cdf10
|
|
https://github.com/ruby/mmtk/commit/9f730cc709
|
|
Adds MMTK_HEAP_MODE=cpu, a dynamic heap-sizing policy that grows
or shrinks the heap after each GC cycle to keep measured GC CPU
overhead near a configurable target. The control law follows
Tavakolisomeh et al., 'Heap Size Adjustment with CPU Control', MPLR
'23: a sigmoid of the (averaged) GC CPU overhead error in (-inf, +inf)
maps to a heap-size adjustment factor in (0.5, 1.5).
Implementation lives alongside the existing 'ruby' delegated trigger
in gc/mmtk/src/heap/. T_GC is wall-clock GC duration; T_APP is process
CPU time delta read via clock_gettime(CLOCK_PROCESS_CPUTIME_ID), which
correctly credits multi-threaded mutator parallelism. Nursery-only
generational GCs are skipped so the trigger only re-sizes at full
collections.
Configuration:
MMTK_GC_CPU_TARGET target GC CPU overhead, percent. Default 5.
MMTK_GC_CPU_WINDOW number of recent cycles averaged. Default 3.
The default differs from the paper's recommended 15. The paper
targets ZGC, a concurrent generational collector; MMTk-Ruby currently
ships stop-the-world Immix, where every percent of GC CPU also blocks
the mutator. An empirical sweep of MMTK_GC_CPU_TARGET across
ruby-bench (railsbench, lobsters, psych-load, liquid-render, lee)
found 5-6 to be Pareto-optimal vs the existing 'ruby' heap mode:
about 6 percent geomean throughput improvement at essentially equal
peak RSS. Targets >=10 trade large amounts of throughput for modest
RSS savings on this collector.
bin/smoke-test, bin/ruby-mmtk-mode, bin/compare-heap-modes, and
doc/testing-cpu-heap-mode.md are included so reviewers and future
contributors can reproduce the sweep against ruby/ruby-bench.
https://github.com/ruby/mmtk/commit/1f223f5ad5
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
gc/mmtk/mmtk.c:480:1: warning: function 'rb_mmtk_gc_thread_bug' could be declared with attribute 'noreturn' [-Wmissing-noreturn]
480 | {
| ^
gc/mmtk/mmtk.c:510:1: warning: function 'rb_mmtk_mutator_thread_panic_handler' could be declared with attribute 'noreturn' [-Wmissing-noreturn]
510 | {
| ^
https://github.com/ruby/mmtk/commit/a57746d575
|
|
https://github.com/ruby/mmtk/commit/40053354bd
|
|
https://github.com/ruby/mmtk/commit/9772a1d30a
|
|
https://github.com/ruby/mmtk/commit/a46b68fe5b
|
|
Don't need to call it after https://github.com/ruby/ruby/pull/16961.
https://github.com/ruby/mmtk/commit/ae5638ac00
|
|
We can stop using rb_gc_worker_thread_set_vm_context because rb_gc_event_hook
now uses rb_gc_get_ec since https://github.com/ruby/ruby/pull/16880
https://github.com/ruby/mmtk/commit/04bcf8456a
|
|
the only caller of this unconditionally constructs a binding options
object now, So actually this is dead code
https://github.com/ruby/mmtk/commit/d832004e89
|
|
This is a debug mode in Ruby where an extra word is used after each
object to store the address of the Ractor that owns the object, used for
debug purposes only.
While we're working on Ractors, we also need to be able to test with
MMTk enabled, so we should introduce support for this to the MMTk
binding as well.
As implemented we'll default the binding options to have everything
disabled and hardcoded to 0, as was always the case, but if
RACTOR_CHECK_MODE is enabled, we'll build and pass a valid RubyBinding
object to MMTk.
https://github.com/ruby/mmtk/commit/83cb291313
|
|
Since EC is thread-local, we previously used rb_gc_worker_thread_set_vm_context
in MMTk worker threads to temporarily set the EC. However, this was inelegant
and also occasionally caused crashes when marking threads/fibers for the
current EC since it will mark the current machine stack twice (once during
root marking and once for the fiber). However, since the machine
stack is actively being used, the contents may be different when marking
the fiber. Since all objects on the machine stack are pinned, this may
cause an unpinned object to be pinned, which is not allowed in Immix.
The following crash can be observed:
Object 0x200fffbc7d8 is trying to pin 0x200ffc80188
0: mmtk_ruby::handle_gc_thread_panic
1: mmtk_ruby::set_panic_hook::{{closure}}
2: <alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::Fn<(&'a std::panic::PanicHookInfo<'b>,), Output = ()> + core::marker::Sync + core::marker::Send> as core::ops::function::Fn<(&std::panic::PanicHookInfo,)>>::call
at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/alloc/src/boxed.rs:2254:9
3: std::panicking::panic_with_hook
at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:833:13
4: std::panicking::panic_handler::{closure#0}
at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:698:13
5: std::sys::backtrace::__rust_end_short_backtrace::<std::panicking::panic_handler::{closure#0}, !>
at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/sys/backtrace.rs:182:18
6: __rustc::rust_begin_unwind
at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:689:5
7: core::panicking::panic_fmt
at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/panicking.rs:80:14
8: <mmtk_ruby::scanning::VMScanning as mmtk::vm::scanning::Scanning<mmtk_ruby::Ruby>>::scan_object_and_trace_edges::{{closure}}
9: mmtk_ruby::abi::ObjectClosure::c_function_registered
10: rb_mmtk_call_object_closure
at gc/mmtk/mmtk.c:976:19
11: rb_gc_impl_mark_and_pin
at gc/mmtk/mmtk.c:1008:5
12: rb_gc_impl_mark_and_pin
at gc/mmtk/mmtk.c:1004:1
13: gc_mark_maybe_internal
at gc.c:2908:5
14: gc_mark_maybe_internal
at gc.c:2906:1
15: gc_mark_maybe_each_location
at gc.c:2939:5
16: gc_mark_maybe_each_location
at gc.c:2937:1
17: each_location
at gc.c:2924:9
18: each_location_ptr
at gc.c:2933:5
19: each_location_ptr
at gc.c:2930:1
20: rb_gc_mark_machine_context
at gc.c:3200:5
21: rb_execution_context_mark
at vm.c:3768:9
22: cont_mark
at cont.c:1155:5
23: fiber_mark
at cont.c:1284:5
24: rb_mmtk_call_gc_mark_children
at gc/mmtk/mmtk.c:318:5
25: <mmtk_ruby::scanning::VMScanning as mmtk::vm::scanning::Scanning<mmtk_ruby::Ruby>>::scan_object_and_trace_edges::{{closure}}
|
|
Add GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] to store the usable size
(excluding debug overhead) of the smallest pool that can hold a standard
RVALUE.
|
|
Replace the RVALUE_SLOT_SIZE-multiplier based pool sizes with explicit
power-of-two (and near-power-of-two) slot sizes. On 64-bit this gives
12 heaps (32, 40, 64, 80, 96, 128, 160, 256, 512, 640, 768, 1024)
instead of 5, providing finer granularity and less internal
fragmentation. On 32-bit the layout is 5 heaps (32, 64, 128, 256, 512).
|
|
Outputs the number of GC cycles that are moving.
https://github.com/ruby/mmtk/commit/fef8f04186
|
|
Also remove BASE_SLOT_SIZE.
|
|
https://github.com/ruby/mmtk/commit/7889da7c0e
|
|
Instead of sending all 128 buffered objects to one bucket,
round-robin distribute them across all worker buckets so
parallel obj_free work stays balanced.
https://github.com/ruby/mmtk/commit/e1f926cd21
|
|
shutdown_call_finalizer reads candidates from the Rust-side
WeakProcessor, but the main ractor's C-side buffer may not
have been flushed yet (ractor_cache_free runs later). Flush
all remaining buffers before reading candidates.
https://github.com/ruby/mmtk/commit/7e01232134
|
|
https://github.com/ruby/mmtk/commit/26ec9f7f89
|
|
Previously, every object allocation in rb_gc_impl_new_obj made a
per-object FFI call into Rust (mmtk_add_obj_free_candidate), which
acquired a mutex on one of the WeakProcessor's candidate vecs, pushed a
single element, and released the mutex. That's an FFI crossing + mutex
lock/unlock on every single allocation.
Now, each MMTk_ractor_cache has two local buffers (parallel-freeable and
non-parallel-freeable, 128 entries each). On allocation, we just store
the pointer into the local buffer. When a buffer fills up, we flush the
entire batch in one FFI call using mmtk_add_obj_free_candidates, which
does a single mutex acquisition and extend_from_slice for the whole
batch.
We picked 128 as our buffer size at random. We should probably
investigate further what an optimum size for this is
https://github.com/ruby/mmtk/commit/23c4a9a676
|
|
https://github.com/ruby/mmtk/commit/039fa648fe
|
|
Bumps the cargo group with 1 update in the /gc/mmtk directory: [git2](https://github.com/rust-lang/git2-rs).
Updates `git2` from 0.20.2 to 0.20.4
- [Changelog](https://github.com/rust-lang/git2-rs/blob/git2-0.20.4/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/git2-0.20.2...git2-0.20.4)
---
updated-dependencies:
- dependency-name: git2
dependency-version: 0.20.4
dependency-type: indirect
dependency-group: cargo
...
Signed-off-by: dependabot[bot] <support@github.com>
|
|
https://github.com/ruby/mmtk/commit/86fa2fd4af
|
|
https://github.com/ruby/mmtk/commit/002faa8f92
|
|
https://github.com/ruby/mmtk/commit/ae69d69768
|
|
https://github.com/ruby/mmtk/commit/e2a89d5a22
|
|
https://github.com/ruby/mmtk/commit/a31deee342
|
|
https://github.com/ruby/mmtk/commit/e92baf15ef
|
|
https://github.com/ruby/mmtk/commit/e5e2c1c347
|
|
https://github.com/ruby/mmtk/commit/87290e45b2
|
|
https://github.com/ruby/mmtk/commit/59d27203e2
|
|
https://github.com/ruby/mmtk/commit/e34d5cf32f
|
|
https://github.com/ruby/mmtk/commit/350625ebb3
|
|
https://github.com/ruby/mmtk/commit/12a3904b04
|
|
https://github.com/ruby/mmtk/commit/8813e76bf8
|
|
Redos commit 544770d which seems to have accidentally been undone in b27d935.
|
|
|
|
https://github.com/ruby/mmtk/commit/308936296a
|
|
This allows the mutator thread to dump its backtrace when a GC thread crashes.
https://github.com/ruby/mmtk/commit/40ff9ffee7
|
|
https://github.com/ruby/mmtk/commit/c3e338bb25
|
|
https://github.com/ruby/mmtk/commit/58210c88ed
|
|
https://github.com/ruby/mmtk/commit/42adba630e
|
|
The argument to `is_data_encoding` is assumed to be `T_DATA`.
|
|
This makes it easier to visualize in profilers which one is non-parallel.
https://github.com/ruby/mmtk/commit/ba68b2ef3b
|
|
This commit allows objects that are safe to be freed in parallel to do so.
A decrease in object freeing time can be seen in profiles.
The benchmarks don't show much difference.
Before:
-------------- -------------------- ---------- ---------
bench sequential free (ms) stddev (%) RSS (MiB)
activerecord 242.3 7.4 84.3
chunky-png 439.1 0.6 75.6
erubi-rails 1221.2 4.2 132.7
hexapdf 1544.8 1.8 429.1
liquid-c 42.7 7.4 48.5
liquid-compile 41.4 8.3 52.2
liquid-render 100.6 3.0 56.8
mail 108.9 2.1 65.1
psych-load 1536.9 0.6 43.4
railsbench 1633.5 2.6 146.2
rubocop 126.5 15.8 142.1
ruby-lsp 129.6 9.7 112.2
sequel 47.9 6.5 44.6
shipit 1152.0 2.7 315.2
-------------- -------------------- ---------- ---------
After:
-------------- ------------------ ---------- ---------
bench parallel free (ms) stddev (%) RSS (MiB)
activerecord 235.1 5.5 87.4
chunky-png 440.8 0.8 68.1
erubi-rails 1105.3 0.8 128.0
hexapdf 1578.3 4.1 405.1
liquid-c 42.6 7.1 48.4
liquid-compile 41.5 8.1 52.1
liquid-render 101.2 2.8 53.3
mail 109.7 2.7 64.8
psych-load 1567.7 1.1 44.4
railsbench 1644.9 1.9 150.9
rubocop 125.6 15.4 148.5
ruby-lsp 127.9 5.8 104.6
sequel 48.2 6.1 44.1
shipit 1215.3 4.7 320.5
-------------- ------------------ ---------- ---------
https://github.com/ruby/mmtk/commit/4f0b5fd2eb
|
|
https://github.com/ruby/mmtk/commit/290a2aec4e
|
|
|
|
This commit implements moving Immix in MMTk, which allows objects to move
in the GC.
The performance of this implementation is not yet amazing. It is very
similar to non-moving Immix in many of them and slightly slower in others.
The benchmark results is shown below.
-------------- ----------------- ---------- ---------
bench Moving Immix (ms) stddev (%) RSS (MiB)
activerecord 241.9 0.5 86.6
chunky-png 447.8 0.8 74.9
erubi-rails 1183.9 0.8 136.1
hexapdf 1607.9 2.6 402.3
liquid-c 45.4 6.7 44.9
liquid-compile 44.1 9.3 53.0
liquid-render 105.4 4.5 55.9
lobsters 650.1 9.7 418.4
mail 115.4 2.1 64.4
psych-load 1656.8 0.8 43.6
railsbench 1653.5 1.3 149.8
rubocop 127.0 15.6 142.1
ruby-lsp 130.7 10.5 99.4
sequel 52.8 7.2 45.6
shipit 1187.0 3.9 311.0
-------------- ----------------- ---------- ---------
-------------- --------------------- ---------- ---------
bench Non-moving Immix (ms) stddev (%) RSS (MiB)
activerecord 218.9 2.7 86.1
chunky-png 464.6 0.8 66.7
erubi-rails 1119.0 4.3 132.7
hexapdf 1539.8 1.8 425.2
liquid-c 40.6 6.9 45.2
liquid-compile 40.6 8.1 52.9
liquid-render 99.3 2.3 48.3
mail 107.4 5.3 65.4
psych-load 1535.6 1.0 39.5
railsbench 1565.6 1.1 149.6
rubocop 122.5 14.3 146.7
ruby-lsp 128.4 10.7 106.4
sequel 44.1 4.0 45.7
shipit 1154.5 2.7 358.5
-------------- --------------------- ---------- ---------
|