-
Notifications
You must be signed in to change notification settings - Fork 4
Description
The function rb_gc_mark_roots expects itself to be called by a thread that has EC. In the default GC, a CRuby thread starts to play the role of a GC thread when it triggers GC, and it has a EC. The CRuby thread that triggers GC eagerly saves the register state and stack top to its EC, and eagerly scans its own stack so that it can continue executing while incremental GC happens later, scanning the stacks of other CRuby stacks.
When using MMTk, all stack scanning is done by GC worker threads (which do not have CRuby-level EC). They reach all stacks via rb_gc_mark_roots -> rb_vm_mark -> ractors -> threads -> fibers -> stacks. And all GCs are STW. (Currently the MMTk core does not have incremental GC, and the concurrent GC (LXR) is not merged into the master branch.) We only need to guarantee that all mutator threads save their machine states in block_for_gc.
struct objspace::vm_context is a workaround so that rb_gc_mark_roots will not complain about the missing EC in the GC worker thread. Currently we set it to the EC of the last CRuby thread that calls block_for_gc. But we don't really need that because all ECs will be reached from rb_vm_mark.
We need a change in https://github.com/ruby/ruby to allow rb_gc_mark_roots if it is not called from a GC worker thread. There are several options:
- We add a parameter to
rb_gc_mark_rootto make itrb_gc_mark_roots(objspace, categoryp, scan_current_ec). Third-party GC modules can passfalsetoscan_current_ecif GC is done by non-CRuby threads. - We let
rb_gc_mark_rootskipmark_current_machine_context(ec)if the current thread does not have a EC.