summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-18 09:02:10 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-18 09:02:10 +0000
commitec4624b0f47ee6a99036b1711bd5746cdd99da33 (patch)
treebd853ce990695ca4895052354726d49381c05fe7 /gc.c
parent3b1e28036e318d06b5e2f4f65f709ad483aa40ec (diff)
* 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). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50006 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index af7f815db1..fd397983de 100644
--- a/gc.c
+++ b/gc.c
@@ -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