set.c: use rb_gc_mark_and_move

The `p->field = rb_gc_location(p->field)` isn't ideal because it means all
references are rewritten on compaction, regardless of whether the referenced
object has moved. This isn't good for caches nor for Copy-on-Write.

`rb_gc_mark_and_move` avoid needless writes, and most of the time allow to
have a single function for both marking and updating references.
This commit is contained in:
Jean Boussier 2025-08-07 14:44:48 +02:00
parent 559d9e1f67
commit 5bcfc53d6f

4
set.c
View file

@ -172,9 +172,7 @@ set_foreach_replace(st_data_t key, st_data_t argp, int error)
static int
set_replace_ref(st_data_t *key, st_data_t argp, int existing)
{
if (rb_gc_location((VALUE)*key) != (VALUE)*key) {
*key = rb_gc_location((VALUE)*key);
}
rb_gc_mark_and_move((VALUE *)key);
return ST_CONTINUE;
}