diff options
author | Peter Zhu <[email protected]> | 2024-12-13 12:20:30 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2024-12-16 10:12:54 -0500 |
commit | 15765eac0ae156afe69b53ab317c4096f2c2c0ec (patch) | |
tree | 6615a2f65bea67e8cf937b44f480dd31962e83cc /ext/objspace/object_tracing.c | |
parent | b0385305060e6edf98f92993f3f13c5e6a978b0e (diff) |
Fix ObjectSpace.trace_object_allocations for compaction
We need to reinsert into the ST table when an object moves because it is
a numtable that hashes on the object address, so when an object moves we
need to reinsert it rather than just updating the key.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/12339
Diffstat (limited to 'ext/objspace/object_tracing.c')
-rw-r--r-- | ext/objspace/object_tracing.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/ext/objspace/object_tracing.c b/ext/objspace/object_tracing.c index b92fda6826..8ea35ef7b7 100644 --- a/ext/objspace/object_tracing.c +++ b/ext/objspace/object_tracing.c @@ -190,20 +190,19 @@ allocation_info_tracer_memsize(const void *ptr) } static int -hash_foreach_should_replace_key(st_data_t key, st_data_t value, st_data_t argp, int error) +allocation_info_tracer_compact_update_object_table_i(st_data_t key, st_data_t value, st_data_t data) { - VALUE allocated_object = (VALUE)key; - if (allocated_object != rb_gc_location(allocated_object)) { - return ST_REPLACE; - } + st_table *table = (st_table *)data; - return ST_CONTINUE; -} + if (key != rb_gc_location(key)) { + DURING_GC_COULD_MALLOC_REGION_START(); + { + st_insert(table, rb_gc_location(key), value); + } + DURING_GC_COULD_MALLOC_REGION_END(); -static int -hash_replace_key(st_data_t *key, st_data_t *value, st_data_t argp, int existing) -{ - *key = rb_gc_location((VALUE)*key); + return ST_DELETE; + } return ST_CONTINUE; } @@ -214,7 +213,10 @@ allocation_info_tracer_compact(void *ptr) struct traceobj_arg *trace_arg = (struct traceobj_arg *)ptr; if (trace_arg->object_table && - st_foreach_with_replace(trace_arg->object_table, hash_foreach_should_replace_key, hash_replace_key, 0)) { + st_foreach( + trace_arg->object_table, + allocation_info_tracer_compact_update_object_table_i, + (st_data_t)trace_arg->object_table)) { rb_raise(rb_eRuntimeError, "hash modified during iteration"); } } |