mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Batch cleanup geniv before sweep
Previously we needed to check every object to determine whether or not it might have an entry in the geniv table. This commit adds a function, rb_gc_vm_weak_table_essential_p, which allows gc.c to decide which tables to always handle in batch. MMTK will continue to call rb_gc_vm_weak_table_foreach on all tables. This only changes the default GC to sweep the "essential" tables first, but continue to call rb_gc_obj_free_vm_weak_references on other objects. This makes the geniv table "essental", as it's usually small and needs to be tested on every type of object. It leaves the fstring table, symbol table, callinfo table, and overloaded CME table as-is because those tables are (mostly) larger and are only needed by specific object types.
This commit is contained in:
1 parent
a758990d44
commit
f7eca0d41e
3 files changed
+35
-9
Notes:
git
2026-07-15 20:54:42 +00:00
No files matched your search
@@ -1411,11 +1411,6 @@ rb_gc_obj_needs_cleanup_p(VALUE obj)
|
||||
return rb_gc_imemo_needs_cleanup_p(obj);
|
||||
}
|
||||
|
||||
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
|
||||
if (rb_shape_has_fields(shape_id) && rb_shape_layout(shape_id) == SHAPE_ID_LAYOUT_OTHER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (flags & RUBY_T_MASK) {
|
||||
case T_FLOAT:
|
||||
case T_RATIONAL:
|
||||
@@ -2162,10 +2157,6 @@ rb_gc_obj_free_vm_weak_references(VALUE obj)
|
||||
{
|
||||
ASSUME(!RB_SPECIAL_CONST_P(obj));
|
||||
|
||||
if (rb_obj_gen_fields_p(obj)) {
|
||||
rb_free_generic_ivar(obj);
|
||||
}
|
||||
|
||||
switch (BUILTIN_TYPE(obj)) {
|
||||
case T_STRING:
|
||||
if (FL_TEST_RAW(obj, RSTRING_FSTR)) {
|
||||
@@ -4048,6 +4039,20 @@ vm_weak_table_frozen_strings_foreach(VALUE *str, void *data)
|
||||
}
|
||||
|
||||
void rb_fstring_foreach_with_replace(int (*callback)(VALUE *str, void *data), void *data);
|
||||
|
||||
// Whether this table must be cleaned every GC after marking.
|
||||
// Other tables may be skipped cleaned up per-object via rb_gc_obj_free_vm_weak_references.
|
||||
bool
|
||||
rb_gc_vm_weak_table_essential_p(enum rb_gc_vm_weak_tables table)
|
||||
{
|
||||
switch (table) {
|
||||
case RB_GC_VM_GENERIC_FIELDS_TABLE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback,
|
||||
vm_table_update_callback_func update_callback,
|
||||
|
||||
@@ -4232,6 +4232,15 @@ gc_sweep_freeobj_hooks(rb_objspace_t *objspace)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gc_sweep_weak_table_i(VALUE val, void *data)
|
||||
{
|
||||
rb_objspace_t *objspace = data;
|
||||
if (RB_SPECIAL_CONST_P(val)) return ST_CONTINUE;
|
||||
if (RVALUE_MARKED(objspace, val)) return ST_CONTINUE;
|
||||
return ST_DELETE;
|
||||
}
|
||||
|
||||
static void
|
||||
gc_sweep_start(rb_objspace_t *objspace)
|
||||
{
|
||||
@@ -4242,6 +4251,17 @@ gc_sweep_start(rb_objspace_t *objspace)
|
||||
gc_sweep_freeobj_hooks(objspace);
|
||||
}
|
||||
|
||||
for (int table = 0; table < RB_GC_VM_WEAK_TABLE_COUNT; table++) {
|
||||
if (!rb_gc_vm_weak_table_essential_p(table)) continue;
|
||||
rb_gc_vm_weak_table_foreach(
|
||||
gc_sweep_weak_table_i,
|
||||
NULL,
|
||||
objspace,
|
||||
true,
|
||||
table
|
||||
);
|
||||
}
|
||||
|
||||
#if GC_CAN_COMPILE_COMPACTION
|
||||
if (objspace->flags.during_compacting) {
|
||||
gc_sort_heap_by_compare_func(
|
||||
|
||||
@@ -92,6 +92,7 @@ MODULAR_GC_FN void rb_gc_vm_unlock_no_barrier(unsigned int lev, const char *file
|
||||
MODULAR_GC_FN void rb_gc_vm_barrier(void);
|
||||
MODULAR_GC_FN size_t rb_gc_obj_optimal_size(VALUE obj);
|
||||
MODULAR_GC_FN void rb_gc_mark_children(void *objspace, VALUE obj);
|
||||
MODULAR_GC_FN bool rb_gc_vm_weak_table_essential_p(enum rb_gc_vm_weak_tables table);
|
||||
MODULAR_GC_FN 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);
|
||||
MODULAR_GC_FN void rb_gc_update_object_references(void *objspace, VALUE obj);
|
||||
MODULAR_GC_FN void rb_gc_update_vm_references(void *objspace);
|
||||
|
||||
Reference in new issue
Block a user