Project

General

Profile

Feature #16984

Updated by alanwu (Alan Wu) almost 2 years ago

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 `I`, 
 `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 
 modules. 

 --- 

 Patch: https://github.com/ruby/ruby/pull/3410 

 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](https://github.com/ruby/ruby/commit/37e6c83609ac9d4c30ca4660ee16701e53cf82a3). iclasses](https://github.com/ruby/ruby/commit/37e6c83609ac9d4c30ca4660ee16701e53cf82a3) 
 I measured again and an app that has an approximately 250MiB heap 
 saw a 22% reduction in minor GC time. 
 
 Credits to @tenderlovemaking for motivating this change. 

Back