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:
parent
790a1b1790
commit
c9b74f9fd9
1 changed files with 15 additions and 1 deletions
16
gc.c
16
gc.c
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue