Remove write barrier exemption for T_ICLASS
Currently, iclasses are "shady", or not protected by write
barriers. Because of that, the GC needs to spend more time marking these
objects than otherwise. Let's insert write barriers for iclasses.
Applications that use modules heavily should see reduction in GC
time as they have a significant number of live iclasses on the heap.
- Put logic for iclass method table ownership into a function
- Remove calls to WB_UNPROTECT and insert write barriers for iclasses
The change relies on the following invariant: for any non origin iclass
RCLASS_M_TBL(I) == RCLASS_M_TBL(RBasic(I)->klass). This invariant
did not hold prior to 98286e9 for classes and modules that have prepended
This is the second version of this change. It's much simpler and it
doesn't introduce new garbage collected objects. I realized that despite
saving a pointer to some other object's method table, iclasses don't
mark the method tables. So, for each method table, there is an unique
object that's responsible for marking it. Since write barriers are only
needed for the object that is marking the newly written value (correct me
if I'm wrong here), having an unique object that marks the tables
makes things straight forward.
The numbers from v1 of this patch was a bit inflated because we were
allocating an excessive amount of iclasses.
I measured again and an app that has an approximately 250MiB heap
saw a 22% reduction in minor GC time.
Credits to @tenderlovemaking (Aaron Patterson) for motivating this change.