Skip to content

Reorganize src/scheduler/gc_work.rs #1279

Open
@wks

Description

@wks

The file src/scheduler/gc_work.rs contains about 1200 lines of code, with more than 20 structs and more than 50 impl items.

  • There are simply too many items, and
  • they are not ordered or grouped in the way they are used. Not by use cases, and not in the temporal order in a GC.

This made it difficult for developers to find the right type or function when they want to make modification to MMTk. But one design goal of MMTk is to make this easy.

Reorganizing this file into multiple files

We can categorize the work packets and traits by their use cases.

Unless specified, items listed below are struct items.

  • Generic GC scheduling work packets.
    • ScheduleCollection
    • StopMutators
    • Prepare
    • PrepareMutator
    • PrepareCollector
    • Release
    • ReleaseMutator
    • ReleaseCollector
    • VMPostForwarding (running concurrently with Release)
  • Root scanning
    • ScanMutatorRoots
    • ScanVMSpecificRoots
    • ProcessEdgesWorkRootsWorkFactory (implements RootsWorkFactory defined in src/vm/scanning.rs)
    • enum RootsKind
  • Tracing (transitive closure)
    • Slots/edges
      • ProcessEdgesBase (This is all about processing slots instead of edges).
      • trait ProcessEdgesWork (This part really needs to be refactored. ProcessEdgesWork::trace_object shouldn't be specific to slot-enqueued tracing.)
      • SFTProcessEdges
      • PlanProcessEdges
      • ProcessEdgesWorkTracer (implements ObjectTracer defined in src/vm/scanning.rs)
      • UnsupportedProcessEdges
    • Nodes
      • trait ScanObjectsWork
      • ScanObjects
      • PlanScanObjects
      • ProcessRootNode (for pinning and transitive-pinning roots)
  • Finalizer and weak references
    • ProcessEdgesWorkTracerContext (implements TracerContext defined in src/vm/scanning.rs)
    • VMProcessWeakRefs
    • VMForwardWeakRefs

Refactoring slots-processing work packets

In the early stage of the Rust port, MMTk was very focused on slot-enqueuing tracing because that's what OpenJDK and JikesRVM do. One design decision which I think is bad is that it mixed up "edge processing" and "slots processing".

  • Slot processing: For each slot in a list of slots, load from it, call trace_object, and store back forwarded reference.
  • Edge visiting: The trace_object(obj) -> new_obj method. This effectively visits an object graph edge that points to obj, regardless whether obj is loaded from a given Slot or obtained in VM-specific ways in Scanning::scan_object_and_trace_edges. In the end, if a VM binding only supports node-enqueuing tracing (such as Ruby), we have to wrap ProcessEdgesWork behind the ObjectTracer trait which only provides the trace_object method (that is, ProcessEdgesWorkTracer).

I had a branch that refactors the trace_object into a dedicated type and leaves the ProcessEdgesWork dedicated to slot processing. The code is here: #1278, but it is very old.

And #599 contains more information about my intended refactoring.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions