diff options
| -rw-r--r-- | gc/default/default.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/gc/default/default.c b/gc/default/default.c index 1288a44b8e..9b40fed097 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -4544,6 +4544,28 @@ pin_value(st_data_t key, st_data_t value, st_data_t data) return ST_CONTINUE; } +static inline void +gc_mark_set_parent_raw(rb_objspace_t *objspace, VALUE obj, bool old_p) +{ + asan_unpoison_memory_region(&objspace->rgengc.parent_object, sizeof(objspace->rgengc.parent_object), false); + asan_unpoison_memory_region(&objspace->rgengc.parent_object_old_p, sizeof(objspace->rgengc.parent_object_old_p), false); + objspace->rgengc.parent_object = obj; + objspace->rgengc.parent_object_old_p = old_p; +} + +static inline void +gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj) +{ + gc_mark_set_parent_raw(objspace, obj, RVALUE_OLD_P(objspace, obj)); +} + +static inline void +gc_mark_set_parent_invalid(rb_objspace_t *objspace) +{ + asan_poison_memory_region(&objspace->rgengc.parent_object, sizeof(objspace->rgengc.parent_object)); + asan_poison_memory_region(&objspace->rgengc.parent_object_old_p, sizeof(objspace->rgengc.parent_object_old_p)); +} + static void mark_roots(rb_objspace_t *objspace, const char **categoryp) { @@ -4552,8 +4574,7 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp) } while (0) MARK_CHECKPOINT("objspace"); - objspace->rgengc.parent_object = Qundef; - objspace->rgengc.parent_object_old_p = false; + gc_mark_set_parent_raw(objspace, Qundef, false); if (finalizer_table != NULL) { st_foreach(finalizer_table, pin_value, (st_data_t)objspace); @@ -4563,13 +4584,7 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp) rb_gc_save_machine_context(); rb_gc_mark_roots(objspace, categoryp); -} - -static inline void -gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj) -{ - objspace->rgengc.parent_object = obj; - objspace->rgengc.parent_object_old_p = RVALUE_OLD_P(objspace, obj); + gc_mark_set_parent_invalid(objspace); } static void @@ -4577,6 +4592,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) { gc_mark_set_parent(objspace, obj); rb_gc_mark_children(objspace, obj); + gc_mark_set_parent_invalid(objspace); } /** @@ -5986,9 +6002,11 @@ gc_mark_from(rb_objspace_t *objspace, VALUE obj, VALUE parent) { gc_mark_set_parent(objspace, parent); rgengc_check_relation(objspace, obj); - if (gc_mark_set(objspace, obj) == FALSE) return; - gc_aging(objspace, obj); - gc_grey(objspace, obj); + if (gc_mark_set(objspace, obj) != FALSE) { + gc_aging(objspace, obj); + gc_grey(objspace, obj); + } + gc_mark_set_parent_invalid(objspace); } NOINLINE(static void gc_writebarrier_incremental(VALUE a, VALUE b, rb_objspace_t *objspace)); |
