ruby-changes:55984
From: Aaron <ko1@a...>
Date: Tue, 4 Jun 2019 07:17:49 +0900 (JST)
Subject: [ruby-changes:55984] Aaron Patterson: c9b74f9fd9 (trunk): Pin keys in "compare by identity" hashes
https://git.ruby-lang.org/ruby.git/commit/?id=c9b74f9fd9 From c9b74f9fd95113df903fc34cc1d6ec3fb3160c85 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Mon, 3 Jun 2019 15:15:48 -0700 Subject: 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. diff --git a/gc.c b/gc.c index 5a94ca0..19ddf9b 100644 --- a/gc.c +++ b/gc.c @@ -4547,10 +4547,24 @@ mark_keyvalue(st_data_t key, st_data_t value, st_data_t data) https://github.com/ruby/ruby/blob/trunk/gc.c#L4547 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)) { -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/