summaryrefslogtreecommitdiff
path: root/ext/objspace/object_tracing.c
diff options
context:
space:
mode:
authorPeter Zhu <[email protected]>2024-12-13 12:20:30 -0500
committerPeter Zhu <[email protected]>2024-12-16 10:12:54 -0500
commit15765eac0ae156afe69b53ab317c4096f2c2c0ec (patch)
tree6615a2f65bea67e8cf937b44f480dd31962e83cc /ext/objspace/object_tracing.c
parentb0385305060e6edf98f92993f3f13c5e6a978b0e (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.c26
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");
}
}