[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]