ruby-changes:63294
From: Aaron <ko1@a...>
Date: Wed, 7 Oct 2020 08:22:20 +0900 (JST)
Subject: [ruby-changes:63294] cdc4084b0a (master): Prevent objects from moving while iterating the heap
https://git.ruby-lang.org/ruby.git/commit/?id=cdc4084b0a From cdc4084b0a947b87a794394b9cc8cbdb10537146 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Tue, 6 Oct 2020 13:17:21 -0700 Subject: Prevent objects from moving while iterating the heap This iterator uses an st_table, but if objects move the references in the st table won't be updated. This patch just changes the st table to an identity hash. diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c index e5b98a6..0930e10 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -25,6 +25,10 @@ https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L25 #include "ruby/st.h" #include "symbol.h" +#undef rb_funcall + +#include "ruby/ruby.h" + /* * call-seq: * ObjectSpace.memsize_of(obj) -> Integer @@ -707,7 +711,7 @@ iow_internal_object_id(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L711 } struct rof_data { - st_table *refs; + VALUE refs; VALUE internals; }; @@ -723,7 +727,7 @@ reachable_object_from_i(VALUE obj, void *data_ptr) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L727 val = iow_newobj(obj); rb_ary_push(data->internals, val); } - st_insert(data->refs, key, val); + rb_hash_aset(data->refs, key, val); } } @@ -781,20 +785,18 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L785 reachable_objects_from(VALUE self, VALUE obj) { if (rb_objspace_markable_object_p(obj)) { - VALUE ret = rb_ary_new(); struct rof_data data; if (rb_typeddata_is_kind_of(obj, &iow_data_type)) { obj = (VALUE)DATA_PTR(obj); } - data.refs = st_init_numtable(); + data.refs = rb_ident_hash_new(); data.internals = rb_ary_new(); rb_objspace_reachable_objects_from(obj, reachable_object_from_i, &data); - st_foreach(data.refs, collect_values, (st_data_t)ret); - return ret; + return rb_funcall(data.refs, rb_intern("values"), 0); } else { return Qnil; -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/