Use rb_gc_vm_weak_table_foreach for reference updating

We can use rb_gc_vm_weak_table_foreach for reference updating of weak tables
in the default GC.
This commit is contained in:
Peter Zhu 2025-01-24 10:16:27 -05:00
parent 9e5ff79c5b
commit 98b36f6f36
Notes: git 2025-01-27 15:28:55 +00:00
6 changed files with 26 additions and 48 deletions

4
gc.c
View File

@ -3341,7 +3341,6 @@ update_superclasses(void *objspace, VALUE obj)
extern rb_symbols_t ruby_global_symbols;
#define global_symbols ruby_global_symbols
#if USE_MODULAR_GC
struct global_vm_table_foreach_data {
vm_table_foreach_callback_func callback;
vm_table_update_callback_func update_callback;
@ -3596,7 +3595,6 @@ rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback,
rb_bug("rb_gc_vm_weak_table_foreach: unknown table %d", table);
}
}
#endif
void
rb_gc_update_vm_references(void *objspace)
@ -3605,11 +3603,9 @@ rb_gc_update_vm_references(void *objspace)
rb_vm_t *vm = rb_ec_vm_ptr(ec);
rb_vm_update_references(vm);
rb_generic_ivar_update_references();
rb_gc_update_global_tbl();
global_symbols.ids = gc_location_internal(objspace, global_symbols.ids);
global_symbols.dsymbol_fstr_hash = gc_location_internal(objspace, global_symbols.dsymbol_fstr_hash);
gc_update_table_refs(global_symbols.str_sym);
#if USE_YJIT
void rb_yjit_root_update_references(void); // in Rust

View File

@ -7110,6 +7110,20 @@ gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t *objspace,
return 0;
}
static int
gc_update_references_weak_table_i(VALUE obj, void *data)
{
return BUILTIN_TYPE(obj) == T_MOVED ? ST_REPLACE : ST_CONTINUE;
}
static int
gc_update_references_weak_table_replace_i(VALUE *obj, void *data)
{
*obj = rb_gc_location(*obj);
return ST_CONTINUE;
}
static void
gc_update_references(rb_objspace_t *objspace)
{
@ -7140,6 +7154,16 @@ gc_update_references(rb_objspace_t *objspace)
rb_gc_update_vm_references((void *)objspace);
for (int table = 0; table < RB_GC_VM_WEAK_TABLE_COUNT; table++) {
rb_gc_vm_weak_table_foreach(
gc_update_references_weak_table_i,
gc_update_references_weak_table_replace_i,
NULL,
false,
table
);
}
objspace->flags.during_reference_updating = false;
}

View File

@ -19,11 +19,11 @@ struct rb_gc_vm_context {
struct rb_execution_context_struct *ec;
};
#endif
typedef int (*vm_table_foreach_callback_func)(VALUE value, void *data);
typedef int (*vm_table_update_callback_func)(VALUE *value, void *data);
enum rb_gc_vm_weak_tables {
RB_GC_VM_CI_TABLE,
RB_GC_VM_OVERLOADED_CME_TABLE,
@ -32,7 +32,6 @@ enum rb_gc_vm_weak_tables {
RB_GC_VM_FROZEN_STRINGS_TABLE,
RB_GC_VM_WEAK_TABLE_COUNT
};
#endif
RUBY_SYMBOL_EXPORT_BEGIN
unsigned int rb_gc_vm_lock(void);
@ -44,6 +43,7 @@ void rb_gc_vm_unlock_no_barrier(unsigned int lev);
void rb_gc_vm_barrier(void);
size_t rb_gc_obj_optimal_size(VALUE obj);
void rb_gc_mark_children(void *objspace, VALUE obj);
void rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback, vm_table_update_callback_func update_callback, void *data, bool weak_only, enum rb_gc_vm_weak_tables table);
void rb_gc_update_object_references(void *objspace, VALUE obj);
void rb_gc_update_vm_references(void *objspace);
void rb_gc_event_hook(VALUE obj, rb_event_flag_t event);
@ -77,7 +77,6 @@ void *rb_gc_get_ractor_newobj_cache(void);
void rb_gc_initialize_vm_context(struct rb_gc_vm_context *context);
void rb_gc_worker_thread_set_vm_context(struct rb_gc_vm_context *context);
void rb_gc_worker_thread_unset_vm_context(struct rb_gc_vm_context *context);
void rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback, vm_table_update_callback_func update_callback, void *data, bool weak_only, enum rb_gc_vm_weak_tables table);
#endif
RUBY_SYMBOL_EXPORT_END

View File

@ -50,7 +50,6 @@ int rb_gen_ivtbl_get(VALUE obj, ID id, struct gen_ivtbl **ivtbl);
void rb_obj_copy_ivs_to_hash_table(VALUE obj, st_table *table);
void rb_obj_convert_to_too_complex(VALUE obj, st_table *table);
void rb_evict_ivars_to_hash(VALUE obj);
void rb_generic_ivar_update_references(void);
RUBY_SYMBOL_EXPORT_BEGIN
/* variable.c (export) */

View File

@ -1136,42 +1136,6 @@ rb_mark_generic_ivar(VALUE obj)
}
}
static int
rb_generic_ivar_update_references_i(st_data_t key, st_data_t val, st_data_t _data)
{
VALUE orig_obj = (VALUE)key;
VALUE obj = rb_gc_location(orig_obj);
struct gen_ivtbl *ivtbl = (struct gen_ivtbl *)val;
if (rb_shape_obj_too_complex(obj)) {
rb_gc_ref_update_table_values_only(ivtbl->as.complex.table);
}
else {
for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) {
ivtbl->as.shape.ivptr[i] = rb_gc_location(ivtbl->as.shape.ivptr[i]);
}
}
if (obj != orig_obj) {
st_insert(generic_iv_tbl_, (st_data_t)obj, (st_data_t)ivtbl);
return ST_DELETE;
}
else {
return ST_CONTINUE;
}
}
void
rb_generic_ivar_update_references(void)
{
DURING_GC_COULD_MALLOC_REGION_START();
{
st_foreach(generic_iv_tbl_, rb_generic_ivar_update_references_i, (st_data_t)0);
}
DURING_GC_COULD_MALLOC_REGION_END();
}
void
rb_free_generic_ivar(VALUE obj)
{

4
vm.c
View File

@ -2918,8 +2918,6 @@ rb_vm_update_references(void *ptr)
if (ptr) {
rb_vm_t *vm = ptr;
rb_gc_update_tbl_refs(vm->ci_table);
rb_gc_update_tbl_refs(vm->frozen_strings);
vm->mark_object_ary = rb_gc_location(vm->mark_object_ary);
vm->load_path = rb_gc_location(vm->load_path);
vm->load_path_snapshot = rb_gc_location(vm->load_path_snapshot);
@ -2936,8 +2934,6 @@ rb_vm_update_references(void *ptr)
vm->top_self = rb_gc_location(vm->top_self);
vm->orig_progname = rb_gc_location(vm->orig_progname);
rb_gc_update_tbl_refs(vm->overloaded_cme_table);
rb_gc_update_values(RUBY_NSIG, vm->trap_list.cmd);
if (vm->coverages) {