Description
TODO list
- Introduce a context struct for the GC controller, and let it own the data it needs.
- Refactor the initialisation of
GCWorkScheduler
and eliminate the need to use excessiveOption<T>
fields. - Move
ControllerCollectorContext
GCRequester
away fromBasePlan
. Let global states be global.
- Related issue: Cleaning up OOP-style inheritance and the impls of Deref #587
- Fixed in Move some states from BasePlan to GlobalState #949
Problem
Currently, the GCWorkScheduler
serves multiple purposes.
- It owns the
GCWorker
for the GC controller thread. This part should be owned by the GC controller thread. - It serves as the communication hub between mutators, the controller and workers.
- Mutators may add work packets in write barrier.
- workers poll work from the scheduler
- the controller queries worker states, and also get coordinator work from the scheduler
This part should be shared between threads.
On the other hand, there is currently no "context" object for the GC controller thread.
ControllerCollectorContext
contains therun()
method for the GC controller, but it also serves as the communication hub for triggering GC.- It depends on the
GCWorker
in the scheduler. It spends most of its lifetime inGCWorkScheduler::wait_for_completion
. Even its communication channel is owned byGCWorkScheduler.channel.1
.
And the ControllerCollectorContext
-- which apparently has nothing to do with a "plan" --** is buried deep inside mmtk.plan.base().controller_collector_context
**. We consider a "plan" to be a description of a GC algorithm, but BasePlan
holds mostly the global GC states. Understandably, the controller thread itself is one of such global state, but it is really plan-agnostic.
The initialisation process is complicated. When initialising, all GC algorithms pass a scheduler
object to the init()
function of the ControllerCollectorContext
. GCWorkScheduler
also uses many Option<T>
fields and initializes itself unsafely.
These phenomena are a result of porting MMTk from Java to Rust. Java's programming style promotes shared states and inter-referenced objects, while Rust emphasises ownership. This requires us to think more carefully about the ownership of data.
Goal
The goal is to ensure each thread owns the data that it accesses exclusively, and ensure shared data are properly identified, shared and synchronised. Threads we concern include:
- The GC controller
- GC workers (already fixed)
Mutators and VM-specific non-mutator threads (such as OpenJDK's "VM Thread") are not part of our concern.
Data structures we concern include:
ControllerCollectorContext
GCWorkScheduler
MMTK