From 6b08a50a62f3575be4f7f4aeac0d416b8d3cd7c1 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 28 Aug 2024 12:19:12 -0400 Subject: [PATCH] Move checks for special const for marking This commit moves checks to RB_SPECIAL_CONST_P out of the GC implmentation and into gc.c. --- gc.c | 136 ++++++++++++++++++++++++++++++--------------------- gc/default.c | 7 --- 2 files changed, 81 insertions(+), 62 deletions(-) diff --git a/gc.c b/gc.c index bc76f84534..8f990ab0f0 100644 --- a/gc.c +++ b/gc.c @@ -2036,28 +2036,54 @@ ruby_stack_check(void) /* ==================== Marking ==================== */ +static inline void +gc_mark_internal(void *objspace, VALUE obj) +{ + if (RB_SPECIAL_CONST_P(obj)) return; + + rb_gc_impl_mark(objspace, obj); +} + void rb_gc_mark_movable(VALUE obj) { - rb_gc_impl_mark(rb_gc_get_objspace(), obj); + gc_mark_internal(rb_gc_get_objspace(), obj); } void rb_gc_mark_and_move(VALUE *ptr) { + if (SPECIAL_CONST_P(*ptr)) return; + rb_gc_impl_mark_and_move(rb_gc_get_objspace(), ptr); } +static inline void +gc_mark_and_pin_internal(void *objspace, VALUE obj) +{ + if (RB_SPECIAL_CONST_P(obj)) return; + + rb_gc_impl_mark_and_pin(objspace, obj); +} + void rb_gc_mark(VALUE obj) { - rb_gc_impl_mark_and_pin(rb_gc_get_objspace(), obj); + gc_mark_and_pin_internal(rb_gc_get_objspace(), obj); +} + +static inline void +gc_mark_maybe_internal(void *objspace, VALUE obj) +{ + if (RB_SPECIAL_CONST_P(obj)) return; + + rb_gc_impl_mark_maybe(objspace, obj); } void rb_gc_mark_maybe(VALUE obj) { - rb_gc_impl_mark_maybe(rb_gc_get_objspace(), obj); + gc_mark_maybe_internal(rb_gc_get_objspace(), obj); } void @@ -2097,14 +2123,14 @@ gc_mark_locations(void *objspace, const VALUE *start, const VALUE *end, void (*c void rb_gc_mark_locations(const VALUE *start, const VALUE *end) { - gc_mark_locations(rb_gc_get_objspace(), start, end, rb_gc_impl_mark_maybe); + gc_mark_locations(rb_gc_get_objspace(), start, end, gc_mark_maybe_internal); } void rb_gc_mark_values(long n, const VALUE *values) { for (long i = 0; i < n; i++) { - rb_gc_impl_mark(rb_gc_get_objspace(), values[i]); + gc_mark_internal(rb_gc_get_objspace(), values[i]); } } @@ -2112,7 +2138,7 @@ void rb_gc_mark_vm_stack_values(long n, const VALUE *values) { for (long i = 0; i < n; i++) { - rb_gc_impl_mark_and_pin(rb_gc_get_objspace(), values[i]); + gc_mark_and_pin_internal(rb_gc_get_objspace(), values[i]); } } @@ -2121,7 +2147,7 @@ mark_key(st_data_t key, st_data_t value, st_data_t data) { void *objspace = (void *)data; - rb_gc_impl_mark_and_pin(objspace, (VALUE)key); + gc_mark_and_pin_internal(objspace, (VALUE)key); return ST_CONTINUE; } @@ -2139,8 +2165,8 @@ mark_keyvalue(st_data_t key, st_data_t value, st_data_t data) { void *objspace = (void *)data; - rb_gc_impl_mark(objspace, (VALUE)key); - rb_gc_impl_mark(objspace, (VALUE)value); + gc_mark_internal(objspace, (VALUE)key); + gc_mark_internal(objspace, (VALUE)value); return ST_CONTINUE; } @@ -2150,8 +2176,8 @@ pin_key_pin_value(st_data_t key, st_data_t value, st_data_t data) { void *objspace = (void *)data; - rb_gc_impl_mark_and_pin(objspace, (VALUE)key); - rb_gc_impl_mark_and_pin(objspace, (VALUE)value); + gc_mark_and_pin_internal(objspace, (VALUE)key); + gc_mark_and_pin_internal(objspace, (VALUE)value); return ST_CONTINUE; } @@ -2161,8 +2187,8 @@ pin_key_mark_value(st_data_t key, st_data_t value, st_data_t data) { void *objspace = (void *)data; - rb_gc_impl_mark_and_pin(objspace, (VALUE)key); - rb_gc_impl_mark(objspace, (VALUE)value); + gc_mark_and_pin_internal(objspace, (VALUE)key); + gc_mark_internal(objspace, (VALUE)value); return ST_CONTINUE; } @@ -2177,7 +2203,7 @@ mark_hash(void *objspace, VALUE hash) rb_hash_stlike_foreach(hash, mark_keyvalue, (st_data_t)objspace); } - rb_gc_impl_mark(objspace, RHASH(hash)->ifnone); + gc_mark_internal(objspace, RHASH(hash)->ifnone); } void @@ -2191,7 +2217,7 @@ rb_mark_hash(st_table *tbl) static enum rb_id_table_iterator_result mark_method_entry_i(VALUE me, void *objspace) { - rb_gc_impl_mark(objspace, me); + gc_mark_internal(objspace, me); return ID_TABLE_CONTINUE; } @@ -2239,7 +2265,7 @@ gc_mark_machine_stack_location_maybe(void *data, VALUE obj) { void *objspace = ((struct mark_machine_stack_location_maybe_data *)data)->objspace; - rb_gc_impl_mark_maybe(objspace, obj); + gc_mark_maybe_internal(objspace, obj); #ifdef RUBY_ASAN_ENABLED const rb_execution_context_t *ec = ((struct mark_machine_stack_location_maybe_data *)data)->ec; @@ -2251,7 +2277,7 @@ gc_mark_machine_stack_location_maybe(void *data, VALUE obj) &fake_frame_start, &fake_frame_end ); if (is_fake_frame) { - each_stack_location(objspace, ec, fake_frame_start, fake_frame_end, rb_gc_impl_mark_maybe); + each_stack_location(objspace, ec, fake_frame_start, fake_frame_end, gc_mark_maybe_internal); } #endif } @@ -2274,10 +2300,10 @@ static void mark_current_machine_context(void *objspace, rb_execution_context_t *ec) { emscripten_scan_stack(rb_mark_locations); - each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], rb_gc_impl_mark_maybe); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe_internal); emscripten_scan_registers(rb_mark_locations); - each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], rb_gc_impl_mark_maybe); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe_internal); } # else // use Asyncify version @@ -2287,10 +2313,10 @@ mark_current_machine_context(void *objspace, rb_execution_context_t *ec) VALUE *stack_start, *stack_end; SET_STACK_END; GET_STACK_BOUNDS(stack_start, stack_end, 1); - each_stack_location(objspace, ec, stack_start, stack_end, rb_gc_impl_mark_maybe); + each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_maybe_internal); rb_wasm_scan_locals(rb_mark_locations); - each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], rb_gc_impl_mark_maybe); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe_internal); } # endif @@ -2354,7 +2380,7 @@ rb_mark_tbl_i(st_data_t key, st_data_t value, st_data_t data) { void *objspace = (void *)data; - rb_gc_impl_mark_and_pin(objspace, (VALUE)value); + gc_mark_and_pin_internal(objspace, (VALUE)value); return ST_CONTINUE; } @@ -2389,7 +2415,7 @@ mark_cvc_tbl_i(VALUE cvc_entry, void *objspace) entry = (struct rb_cvar_class_tbl_entry *)cvc_entry; RUBY_ASSERT(entry->cref == 0 || (BUILTIN_TYPE((VALUE)entry->cref) == T_IMEMO && IMEMO_TYPE_P(entry->cref, imemo_cref))); - rb_gc_impl_mark(objspace, (VALUE)entry->cref); + gc_mark_internal(objspace, (VALUE)entry->cref); return ID_TABLE_CONTINUE; } @@ -2414,8 +2440,8 @@ mark_const_table_i(VALUE value, void *objspace) { const rb_const_entry_t *ce = (const rb_const_entry_t *)value; - rb_gc_impl_mark(objspace, ce->value); - rb_gc_impl_mark(objspace, ce->file); + gc_mark_internal(objspace, ce->value); + gc_mark_internal(objspace, ce->file); return ID_TABLE_CONTINUE; } @@ -2432,7 +2458,7 @@ rb_gc_mark_roots(void *objspace, const char **categoryp) MARK_CHECKPOINT("vm"); rb_vm_mark(vm); - if (vm->self) rb_gc_impl_mark(objspace, vm->self); + if (vm->self) gc_mark_internal(objspace, vm->self); MARK_CHECKPOINT("machine_context"); mark_current_machine_context(objspace, ec); @@ -2490,17 +2516,17 @@ rb_gc_mark_children(void *objspace, VALUE obj) break; } - rb_gc_impl_mark(objspace, RBASIC(obj)->klass); + gc_mark_internal(objspace, RBASIC(obj)->klass); switch (BUILTIN_TYPE(obj)) { case T_CLASS: if (FL_TEST(obj, FL_SINGLETON)) { - rb_gc_impl_mark(objspace, RCLASS_ATTACHED_OBJECT(obj)); + gc_mark_internal(objspace, RCLASS_ATTACHED_OBJECT(obj)); } // Continue to the shared T_CLASS/T_MODULE case T_MODULE: if (RCLASS_SUPER(obj)) { - rb_gc_impl_mark(objspace, RCLASS_SUPER(obj)); + gc_mark_internal(objspace, RCLASS_SUPER(obj)); } mark_m_tbl(objspace, RCLASS_M_TBL(obj)); @@ -2511,7 +2537,7 @@ rb_gc_mark_children(void *objspace, VALUE obj) } else { for (attr_index_t i = 0; i < RCLASS_IV_COUNT(obj); i++) { - rb_gc_impl_mark(objspace, RCLASS_IVPTR(obj)[i]); + gc_mark_internal(objspace, RCLASS_IVPTR(obj)[i]); } } @@ -2519,7 +2545,7 @@ rb_gc_mark_children(void *objspace, VALUE obj) rb_id_table_foreach_values(RCLASS_CONST_TBL(obj), mark_const_table_i, objspace); } - rb_gc_impl_mark(objspace, RCLASS_EXT(obj)->classpath); + gc_mark_internal(objspace, RCLASS_EXT(obj)->classpath); break; case T_ICLASS: @@ -2527,11 +2553,11 @@ rb_gc_mark_children(void *objspace, VALUE obj) mark_m_tbl(objspace, RCLASS_M_TBL(obj)); } if (RCLASS_SUPER(obj)) { - rb_gc_impl_mark(objspace, RCLASS_SUPER(obj)); + gc_mark_internal(objspace, RCLASS_SUPER(obj)); } if (RCLASS_INCLUDER(obj)) { - rb_gc_impl_mark(objspace, RCLASS_INCLUDER(obj)); + gc_mark_internal(objspace, RCLASS_INCLUDER(obj)); } mark_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj)); rb_cc_table_mark(obj); @@ -2540,13 +2566,13 @@ rb_gc_mark_children(void *objspace, VALUE obj) case T_ARRAY: if (ARY_SHARED_P(obj)) { VALUE root = ARY_SHARED_ROOT(obj); - rb_gc_impl_mark(objspace, root); + gc_mark_internal(objspace, root); } else { long len = RARRAY_LEN(obj); const VALUE *ptr = RARRAY_CONST_PTR(obj); for (long i = 0; i < len; i++) { - rb_gc_impl_mark(objspace, ptr[i]); + gc_mark_internal(objspace, ptr[i]); } } break; @@ -2562,10 +2588,10 @@ rb_gc_mark_children(void *objspace, VALUE obj) * points into the slot of the shared string. There may be code * using the RSTRING_PTR on the stack, which would pin this * string but not pin the shared string, causing it to move. */ - rb_gc_impl_mark_and_pin(objspace, RSTRING(obj)->as.heap.aux.shared); + gc_mark_and_pin_internal(objspace, RSTRING(obj)->as.heap.aux.shared); } else { - rb_gc_impl_mark(objspace, RSTRING(obj)->as.heap.aux.shared); + gc_mark_internal(objspace, RSTRING(obj)->as.heap.aux.shared); } } break; @@ -2578,7 +2604,7 @@ rb_gc_mark_children(void *objspace, VALUE obj) size_t *offset_list = (size_t *)RTYPEDDATA(obj)->type->function.dmark; for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) { - rb_gc_impl_mark(objspace, *(VALUE *)((char *)ptr + offset)); + gc_mark_internal(objspace, *(VALUE *)((char *)ptr + offset)); } } else { @@ -2603,7 +2629,7 @@ rb_gc_mark_children(void *objspace, VALUE obj) uint32_t len = ROBJECT_IV_COUNT(obj); for (uint32_t i = 0; i < len; i++) { - rb_gc_impl_mark(objspace, ptr[i]); + gc_mark_internal(objspace, ptr[i]); } } @@ -2622,36 +2648,36 @@ rb_gc_mark_children(void *objspace, VALUE obj) case T_FILE: if (RFILE(obj)->fptr) { - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->self); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->pathv); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->tied_io_for_writing); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->writeconv_asciicompat); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->writeconv_pre_ecopts); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->encs.ecopts); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->write_lock); - rb_gc_impl_mark(objspace, RFILE(obj)->fptr->timeout); + gc_mark_internal(objspace, RFILE(obj)->fptr->self); + gc_mark_internal(objspace, RFILE(obj)->fptr->pathv); + gc_mark_internal(objspace, RFILE(obj)->fptr->tied_io_for_writing); + gc_mark_internal(objspace, RFILE(obj)->fptr->writeconv_asciicompat); + gc_mark_internal(objspace, RFILE(obj)->fptr->writeconv_pre_ecopts); + gc_mark_internal(objspace, RFILE(obj)->fptr->encs.ecopts); + gc_mark_internal(objspace, RFILE(obj)->fptr->write_lock); + gc_mark_internal(objspace, RFILE(obj)->fptr->timeout); } break; case T_REGEXP: - rb_gc_impl_mark(objspace, RREGEXP(obj)->src); + gc_mark_internal(objspace, RREGEXP(obj)->src); break; case T_MATCH: - rb_gc_impl_mark(objspace, RMATCH(obj)->regexp); + gc_mark_internal(objspace, RMATCH(obj)->regexp); if (RMATCH(obj)->str) { - rb_gc_impl_mark(objspace, RMATCH(obj)->str); + gc_mark_internal(objspace, RMATCH(obj)->str); } break; case T_RATIONAL: - rb_gc_impl_mark(objspace, RRATIONAL(obj)->num); - rb_gc_impl_mark(objspace, RRATIONAL(obj)->den); + gc_mark_internal(objspace, RRATIONAL(obj)->num); + gc_mark_internal(objspace, RRATIONAL(obj)->den); break; case T_COMPLEX: - rb_gc_impl_mark(objspace, RCOMPLEX(obj)->real); - rb_gc_impl_mark(objspace, RCOMPLEX(obj)->imag); + gc_mark_internal(objspace, RCOMPLEX(obj)->real); + gc_mark_internal(objspace, RCOMPLEX(obj)->imag); break; case T_STRUCT: { @@ -2659,7 +2685,7 @@ rb_gc_mark_children(void *objspace, VALUE obj) const VALUE * const ptr = RSTRUCT_CONST_PTR(obj); for (long i = 0; i < len; i++) { - rb_gc_impl_mark(objspace, ptr[i]); + gc_mark_internal(objspace, ptr[i]); } break; diff --git a/gc/default.c b/gc/default.c index 9d0d05c3a1..9461c3d1ec 100644 --- a/gc/default.c +++ b/gc/default.c @@ -4696,7 +4696,6 @@ gc_pin(rb_objspace_t *objspace, VALUE obj) static inline void gc_mark_and_pin(rb_objspace_t *objspace, VALUE obj) { - if (SPECIAL_CONST_P(obj)) return; gc_pin(objspace, obj); gc_mark(objspace, obj); } @@ -4706,8 +4705,6 @@ rb_gc_impl_mark_and_move(void *objspace_ptr, VALUE *ptr) { rb_objspace_t *objspace = objspace_ptr; - if (SPECIAL_CONST_P(*ptr)) return; - if (RB_UNLIKELY(objspace->flags.during_reference_updating)) { GC_ASSERT(objspace->flags.during_compacting); GC_ASSERT(during_gc); @@ -4724,8 +4721,6 @@ rb_gc_impl_mark(void *objspace_ptr, VALUE obj) { rb_objspace_t *objspace = objspace_ptr; - if (RB_SPECIAL_CONST_P(obj)) return; - gc_mark(objspace, obj); } @@ -4734,8 +4729,6 @@ rb_gc_impl_mark_and_pin(void *objspace_ptr, VALUE obj) { rb_objspace_t *objspace = objspace_ptr; - if (RB_SPECIAL_CONST_P(obj)) return; - gc_mark_and_pin(objspace, obj); }