1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Pin keys in "compare by identity" hashes

Hashes that compare by identity care about the location of the object in
memory.  Since they care about the memory location, we can't let them
move.
This commit is contained in:
Aaron Patterson 2019-06-03 15:15:48 -07:00
parent 790a1b1790
commit c9b74f9fd9
No known key found for this signature in database
GPG key ID: 953170BCB4FFAFC6

16
gc.c
View file

@ -4547,10 +4547,24 @@ mark_keyvalue(st_data_t key, st_data_t value, st_data_t data)
return ST_CONTINUE;
}
static int
pin_key_mark_value(st_data_t key, st_data_t value, st_data_t data)
{
rb_objspace_t *objspace = (rb_objspace_t *)data;
gc_mark_and_pin(objspace, (VALUE)key);
gc_mark(objspace, (VALUE)value);
return ST_CONTINUE;
}
static void
mark_hash(rb_objspace_t *objspace, VALUE hash)
{
rb_hash_stlike_foreach(hash, mark_keyvalue, (st_data_t)objspace);
if (rb_hash_compare_by_id_p(hash)) {
rb_hash_stlike_foreach(hash, pin_key_mark_value, (st_data_t)objspace);
} else {
rb_hash_stlike_foreach(hash, mark_keyvalue, (st_data_t)objspace);
}
if (RHASH_AR_TABLE_P(hash)) {
if (objspace->mark_func_data == NULL && RHASH_TRANSIENT_P(hash)) {