How to implement GMS in Parrot.

There is 2 complex things in implementing Generational GC:

  • Skip older generations during marking younger.
  • Properly handle old-to-young pointers.

Usually first part implemented with help of Compacting GC when survived young objects moved into old generation physically. It will require some substantial changes in Parrot's GC. Instead I'm going to add integer generation field into PObj and skip older objects during marking young ones.

Second part can be implemented in various ways - mprotect on old objects, mprotect of whole generations, manually inserting WriteBarriers, etc. But because we have VTABLEs API and most of access to PMCs go through it we can use idea from to insert write barriers automatically.

  • Add VTABLE *write_barrier_variant and normal_variant into VTABLE
  • Patch Pmc2c to create new "write barrier" VTABLE.
  • Every method marked with :write will have body like this
       VTABLE_foo() {
           Parrot_gc_write_barrier(INTERP, SELF);
           SELF->vtable = SELF->vtable->normal_variant;
  • Parrot_gc_write_barrier will add PMC into root set
  • GMS will have current_generation property during mark.
  • Parrot_gc_mark_PMC_alive will skip older objects during marking.
  • When PMC propogated to older generation we will uipdate generation field and replace VTABLE with write_barrier_variant