diff --git a/gc/gc.h b/gc/gc.h index 05f7e87..69e0e0b 100644 --- a/gc/gc.h +++ b/gc/gc.h @@ -194,6 +194,14 @@ gc_mark_tbl_no_pin_i(st_data_t key, st_data_t value, st_data_t data) return ST_CONTINUE; } +static int +gc_mark_set_no_pin_i(st_data_t key, st_data_t value, st_data_t data) +{ + rb_gc_mark_movable((VALUE)key); + + return ST_CONTINUE; +} + static int hash_foreach_replace(st_data_t key, st_data_t value, st_data_t argp, int error) { @@ -232,6 +240,36 @@ gc_update_table_refs(st_table *tbl) } } +static int +rb_set_foreach_replace(st_data_t key, st_data_t value, st_data_t argp, int error) +{ + if (rb_gc_location((VALUE)key) != (VALUE)key) { + return ST_REPLACE; + } + + return ST_CONTINUE; +} + +static int +rb_set_replace_ref(st_data_t *key, st_data_t *value, st_data_t argp, int existing) +{ + if (rb_gc_location((VALUE)*key) != (VALUE)*key) { + *key = rb_gc_location((VALUE)*key); + } + + return ST_CONTINUE; +} + +static void +gc_update_set_refs(st_table *tbl) +{ + if (!tbl || tbl->num_entries == 0) return; + + if (st_foreach_with_replace(tbl, rb_set_foreach_replace, rb_set_replace_ref, 0)) { + rb_raise(rb_eRuntimeError, "hash modified during iteration"); + } +} + static inline size_t xmalloc2_size(const size_t count, const size_t elsize) { diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index 24f0567..96e9e32 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -475,6 +475,7 @@ rb_mmtk_special_const_p(MMTk_ObjectReference object) } RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2) +RBIMPL_ATTR_NORETURN() static void rb_mmtk_gc_thread_bug(const char *msg, ...) { @@ -505,6 +506,7 @@ rb_mmtk_gc_thread_panic_handler(void) rb_mmtk_gc_thread_bug("MMTk GC thread panicked"); } +RBIMPL_ATTR_NORETURN() static void rb_mmtk_mutator_thread_panic_handler(void) {