ruby-core

Mailing list archive

[#117746] [Ruby master Bug#20462] Native threads are no longer reused — "tenderlovemaking (Aaron Patterson) via ruby-core" <ruby-core@...>

Issue #20462 has been reported by tenderlovemaking (Aaron Patterson).

8 messages 2024/05/01

[#117763] [Ruby master Bug#20468] Segfault on safe navigation in for target — "kddnewton (Kevin Newton) via ruby-core" <ruby-core@...>

Issue #20468 has been reported by kddnewton (Kevin Newton).

11 messages 2024/05/03

[#117765] [Ruby master Feature#20470] Extract Ruby's Garbage Collector — "peterzhu2118 (Peter Zhu) via ruby-core" <ruby-core@...>

Issue #20470 has been reported by peterzhu2118 (Peter Zhu).

8 messages 2024/05/03

[#117812] [Ruby master Bug#20478] Circular parameter syntax error rules — "kddnewton (Kevin Newton) via ruby-core" <ruby-core@...>

Issue #20478 has been reported by kddnewton (Kevin Newton).

11 messages 2024/05/08

[#117838] [Ruby master Bug#20485] Simple use of Mutex and Fiber makes GC leak objects with singleton method — "skhrshin (Shintaro Sakahara) via ruby-core" <ruby-core@...>

Issue #20485 has been reported by skhrshin (Shintaro Sakahara).

14 messages 2024/05/12

[#117882] [Ruby master Bug#20490] Process.waitpid2(-1, Process::WNOHANG) misbehaves on Ruby 3.1 & 3.2 with detached process — "stanhu (Stan Hu) via ruby-core" <ruby-core@...>

Issue #20490 has been reported by stanhu (Stan Hu).

7 messages 2024/05/15

[#117905] [Ruby master Bug#20493] Segfault on rb_io_getline_fast — "josegomezr (Jose Gomez) via ruby-core" <ruby-core@...>

Issue #20493 has been reported by josegomezr (Jose Gomez).

14 messages 2024/05/17

[#117918] [Ruby master Bug#20494] Non-default directories are not searched when checking for a gmp header — "lish82 (Hiroki Katagiri) via ruby-core" <ruby-core@...>

Issue #20494 has been reported by lish82 (Hiroki Katagiri).

10 messages 2024/05/19

[#117921] [Ruby master Bug#20495] Running "make clean" deletes critical "coroutine/amd64/Context.S" file and causes "make" to fail — "fallwith (James Bunch) via ruby-core" <ruby-core@...>

Issue #20495 has been reported by fallwith (James Bunch).

7 messages 2024/05/19

[#117929] [Ruby master Feature#20498] Negated method calls — "MaxLap (Maxime Lapointe) via ruby-core" <ruby-core@...>

Issue #20498 has been reported by MaxLap (Maxime Lapointe).

10 messages 2024/05/19

[#117957] [Ruby master Bug#20500] Non-system directories are not searched when checking for jemalloc headers and libs, and building `enc` — "lish82 (Hiroki Katagiri) via ruby-core" <ruby-core@...>

Issue #20500 has been reported by lish82 (Hiroki Katagiri).

12 messages 2024/05/21

[#117968] [Ruby master Bug#20501] ruby SEGV — "akr (Akira Tanaka) via ruby-core" <ruby-core@...>

Issue #20501 has been reported by akr (Akira Tanaka).

15 messages 2024/05/22

[#117992] [Ruby master Bug#20505] Reassigning the block argument in method body keeps old block when calling super with implicit arguments — "Earlopain (A S) via ruby-core" <ruby-core@...>

Issue #20505 has been reported by Earlopain (A S).

7 messages 2024/05/24

[#118003] [Ruby master Bug#20506] Failure compiling Ruby 3.4.0-preview1 on aarch64 on a mac and linux (Ubuntu 24.04) — "schneems (Richard Schneeman) via ruby-core" <ruby-core@...>

Issue #20506 has been reported by schneems (Richard Schneeman).

12 messages 2024/05/24

[#118090] [Ruby master Bug#20513] the feature of kwargs in index methods has been removed without due consideration of utility and compatibility — "bughit (bug hit) via ruby-core" <ruby-core@...>

Issue #20513 has been reported by bughit (bug hit).

16 messages 2024/05/30

[#118110] [Ruby master Bug#20515] --with-gmp is not working - GMP support won't be built — "sorah (Sorah Fukumori) via ruby-core" <ruby-core@...>

Issue #20515 has been reported by sorah (Sorah Fukumori).

8 messages 2024/05/30

[#118128] [Ruby master Bug#20516] The version of rexml in ruby 3.3.2 has not been updated since 3.2.6. — "naitoh (Jun NAITOH) via ruby-core" <ruby-core@...>

Issue #20516 has been reported by naitoh (Jun NAITOH).

13 messages 2024/05/31

[ruby-core:117902] [Ruby master Feature#20470] Extract Ruby's Garbage Collector

From: "katei (Yuta Saito) via ruby-core" <ruby-core@...>
Date: 2024-05-17 00:55:18 UTC
List: ruby-core #117902
Issue #20470 has been updated by katei (Yuta Saito).


+1 for extracting GC implementation of `gc.c` into a separate `gc_impl.c` file.

My motivation: Some of the use cases of Ruby on Wasm (e.g. edge computing platform) do not actually need to collect garbage objects during execution because such a process does not last so long. Splitting out the collector implementation allows us to have light-weight implementation like [no-op GC in JVM](https://openjdk.org/jeps/318). It will be a good fit for such use cases and also be helpful for performance analysis too.

----------------------------------------
Feature #20470: Extract Ruby's Garbage Collector
https://bugs.ruby-lang.org/issues/20470#change-108319

* Author: peterzhu2118 (Peter Zhu)
* Status: Open
----------------------------------------
# Extract Ruby's Garbage Collector

## Background

As described in [[Feature #20351]](https://bugs.ruby-lang.org/issues/20351), we are working on the ability to plug alternative garbage collector implementations into Ruby. Our goal is to allow developers and researchers to create and experiment with new implementations of garbage collectors in Ruby in a simplified way. This will also allow experimentation with different GC implementations in production systems so users can choose the best GC implementation for their workloads.

## Implementation

GitHub PR: [10721](https://github.com/ruby/ruby/pull/10721)

In this patch, we have split the current `gc.c` file into two files: `gc.c` and `gc_impl.c`.

`gc.c` now only contains code not specific to Ruby GC. This includes code to mark objects (which the GC implementation may choose not to use) and wrappers for internal APIs that the implementation may need to use (e.g. locking the VM).

`gc_impl.c` now contains the implementation of Ruby's GC. This includes marking, sweeping, compaction, and statistics. Most importantly, `gc_impl.c` only uses public APIs in Ruby and a limited set of functions exposed in `gc.c`. This allows us to build `gc_impl.c` independently of Ruby and plug Ruby's GC into itself.

## Demonstration

After [checking out the branch](https://github.com/ruby/ruby/pull/10721), we can first configure with `--with-shared-gc`:

```bash
$ ./configure --with-shared-gc
...
$ make -j
...
```

Let's now change the slot size of the GC to 64 bytes:

```bash
$ sed -i 's/\(#define BASE_SLOT_SIZE\).*/\1 64/' gc_impl.c
```

We can compile `gc_impl.c` independently using the following commands for clang or gcc (you may have to change the last `-I` to match your architecture and platform):

```bash
$ clang -Iinclude -I. -I.ext/include/arm64-darwin23 -undefined dynamic_lookup -g -O3 -dynamiclib -o libgc.dylib gc_impl.c
$ gcc -Iinclude -I. -I.ext/include/x86_64-linux -Wl,-undefined,dynamic_lookup -fPIC -g -O3 -shared -o libgc.so gc_impl.c
```

We can see that by default, the slot size is 40 bytes and objects are 40 bytes in size:

```bash
$ ./ruby -e "puts GC.stat_heap(0, :slot_size)"
40
$ ./ruby -robjspace -e "puts ObjectSpace.dump(Object.new)"
{"address":"0x1054a23f0", "type":"OBJECT", "shape_id":3, "slot_size":40, "class":"0x10528fd38", "embedded":true, "ivars":0, "memsize":40, "flags":{"wb_protected":true}}
```

We can now load our new GC using the `RUBY_GC_LIBRARY_PATH` environment variable (note that you may have to change the path to the DSO):

```bash
$ RUBY_GC_LIBRARY_PATH=./libgc.dylib ./ruby -e "puts GC.stat_heap(0, :slot_size)"
64
$ RUBY_GC_LIBRARY_PATH=./libgc.dylib ./ruby -robjspace -e "puts ObjectSpace.dump(Object.new)"
{"address":"0x1038de440", "type":"OBJECT", "shape_id":3, "slot_size":64, "class":"0x10355fc00", "embedded":true, "ivars":0, "memsize":64, "flags":{"wb_protected":true}}
```

## Benchmark

Benchmarks were ran on commit [c78cebb](https://github.com/ruby/ruby/commit/c78cebb469fe56b45ee5daad16ae976b7760497c) on Ubuntu 22.04 using [yjit-bench](https://github.com/Shopify/yjit-bench/) on commit [cc5a76e](https://github.com/Shopify/yjit-bench/commit/cc5a76ef6240113650547bdfb260a87934208321).

Compiling gc_impl branch without `--with-shared-gc` (i.e. how the default Ruby is built), the benchmarks show little to no decrease in performance, with most of it being 0% to 1% slower:

```
--------------  -----------  ----------  ------------  ----------  ---------------  --------------
bench           master (ms)  stddev (%)  gc_impl (ms)  stddev (%)  gc_impl 1st itr  master/gc_impl
activerecord    73.9         0.3         74.6          0.3         1.00             0.99          
chunky-png      911.1        0.2         937.2         0.2         0.97             0.97          
erubi-rails     1582.4       0.1         1583.5        0.0         1.00             1.00          
hexapdf         2716.2       1.1         2760.2        0.7         1.00             0.98          
liquid-c        68.9         0.5         68.6          0.4         1.00             1.00          
liquid-compile  67.9         0.1         68.2          0.2         0.99             1.00          
liquid-render   172.8        0.1         174.9         0.1         0.99             0.99          
lobsters        1033.9       0.4         1036.0        0.3         1.08             1.00          
mail            135.1        0.2         136.5         0.2         0.99             0.99          
psych-load      2250.8       0.1         2274.9        0.3         0.99             0.99          
railsbench      2499.2       0.2         2502.9        0.1         1.00             1.00          
rubocop         178.3        0.5         179.8         0.4         1.00             0.99          
ruby-lsp        116.8        0.1         118.5         0.2         1.00             0.99          
sequel          75.4         0.2         76.2          0.3         0.99             0.99          
--------------  -----------  ----------  ------------  ----------  ---------------  --------------
```

Compiling gc_impl branch with `--with-shared-gc` and loading Ruby's current GC using `RUBY_GC_LIBRARY_PATH`, the benchmarks are still fairly good with performance decrease of only around 1% to 2%:

```
--------------  -----------  ----------  ------------  ----------  ---------------  --------------
bench           master (ms)  stddev (%)  gc_impl (ms)  stddev (%)  gc_impl 1st itr  master/gc_impl
activerecord    74.2         0.2         75.4          0.5         0.98             0.98          
chunky-png      916.3        0.3         933.2         0.1         0.98             0.98          
erubi-rails     1597.6       0.1         1586.3        0.2         1.01             1.01          
hexapdf         2731.4       0.5         2776.8        0.7         1.00             0.98          
liquid-c        68.5         0.1         68.9          0.4         0.97             0.99          
liquid-compile  67.4         0.4         68.3          0.2         0.95             0.99          
liquid-render   171.8        0.1         175.6         0.2         0.97             0.98          
lobsters        1031.9       0.3         1041.4        0.3         0.94             0.99          
mail            135.5        0.4         136.7         0.1         0.99             0.99          
psych-load      2246.0       0.1         2281.3        0.1         0.99             0.98          
railsbench      2490.9       0.0         2490.0        0.1         1.01             1.00          
rubocop         179.8        2.3         180.0         0.4         0.94             1.00          
ruby-lsp        117.3        0.1         118.5         0.1         0.99             0.99          
sequel          75.8         0.5         76.3          0.2         0.99             0.99          
--------------  -----------  ----------  ------------  ----------  ---------------  --------------
```

## Limitations

We recognize that our current implementation does not yet offer the flexibility required for a generic plug-in GC. Specifically, the set of APIs that the plug-in GC has to implement is relatively large, at around 70 functions. Additionally, some of these functions are specific to the current GC.

We would like to emphasize that the API is NOT stable and is subject to change. We will be working on improving this API and reducing the surface area. This will be future work and we're not working on it in this phase.

## Future plans

- Refactor and improve `gc_impl.c`.
- Implement alternate GC implementations, such as the Epsilon GC and [MMTk](https://www.mmtk.io/) to prove that this API allows for alternate implementations of the GC.
- Reduce and improve the API of the GC implementation.
- Benchmark and improve performance of the DSO API.




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- [email protected]
 To unsubscribe send an email to [email protected]
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

In This Thread