diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | gc.c | 24 |
2 files changed, 41 insertions, 3 deletions
@@ -1,3 +1,23 @@ +Wed Mar 18 17:21:12 2015 Koichi Sasada <ko1@atdot.net> + + * gc.c (gc_writebarrier_generational): add an alternative write + barrier (WB) implementation. + When finding reference from [Old obj] to [New obj] by WB, current + implementation marks [Old obj] as remembered old objects and marks + chilldren of [Old obj] at the beggining of marking. + + Added (but disabled) code changes current behaviour. This fix promote + [New obj] to old and marks as a remembered old object. We can assume + "new objects referred from old objects are maybe long-lived old + objects". + + Disadvantage of added algorithm is we may promote unwilling + short-lived objects. For example, consider many new objects push and + pop to an old stack object. All of new objects (short-lived objects) + promote to old objects unexpectedly. + + To compare these behaviour, I add this new code (but disabled it). + Wed Mar 18 17:14:39 2015 Koichi Sasada <ko1@atdot.net> * gc.c (RVALUE_PROMOTE_RAW): rename to RVALUE_OLD_LONG_LIVED_SET() @@ -5464,15 +5464,33 @@ static void gc_writebarrier_generational(rb_objspace_t *objspace, VALUE a, VALUE b) { if (RGENGC_CHECK_MODE) { - if (!RVALUE_OLD_P(a)) rb_bug("rb_gc_writebarrier_generational: %s is not an old object.", obj_info(a)); - if ( RVALUE_OLD_P(b)) rb_bug("rb_gc_writebarrier_generational: %s is an old object.", obj_info(b)); + if (!RVALUE_OLD_P(a)) rb_bug("gc_writebarrier_generational: %s is not an old object.", obj_info(a)); + if ( RVALUE_OLD_P(b)) rb_bug("gc_writebarrier_generational: %s is an old object.", obj_info(b)); if (is_incremental_marking(objspace)) rb_bug("rb_gc_writebarrier_generational: called while incremental marking: %s -> %s", obj_info(a), obj_info(b)); } +#if 1 + /* mark `a' and remember (default behaviour) */ if (!rgengc_remembered(objspace, a)) { - gc_report(1, objspace, "rb_gc_writebarrier_generational: %s -> %s\n", obj_info(a), obj_info(b)); rgengc_remember(objspace, a); + gc_report(1, objspace, "rb_gc_writebarrier_generational: %s (remembered) -> %s\n", obj_info(a), obj_info(b)); + } +#else + /* mark `b' and remember */ + MARK_IN_BITMAP(GET_HEAP_MARK_BITS(b), b); + if (RVALUE_WB_UNPROTECTED(b)) { + gc_remember_unprotected(objspace, b); + } + else { + RVALUE_AGE_SET_OLD(objspace, b); + rgengc_remember(objspace, b); } + + gc_report(1, objspace, "gc_writebarrier_generational: %s -> %s (remembered)\n", obj_info(a), obj_info(b)); +#endif + + check_rvalue_consistency(a); + check_rvalue_consistency(b); } #if GC_ENABLE_INCREMENTAL_MARK |