diff options
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"); } } |