summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-11-08 17:13:11 -0500
committerPeter Zhu <peter@peterzhu.ca>2025-11-08 17:58:25 -0800
commit827f11fce3c92dce80ebc5dc80be9acdafae1173 (patch)
tree3124a892d423c38c9b84500cef12248bf0dc4fd3
parent79eed1158de4164f72def32093aa31bcac339639 (diff)
Move rb_gc_verify_shareable to gc.c
rb_gc_verify_shareable is not GC implementation specific so it should live in gc.c.
-rw-r--r--gc.c78
-rw-r--r--gc/default/default.c61
-rw-r--r--gc/gc.h1
-rw-r--r--gc/gc_impl.h1
-rw-r--r--gc/mmtk/mmtk.c6
5 files changed, 67 insertions, 80 deletions
diff --git a/gc.c b/gc.c
index 92ba02809a..24d897d4bc 100644
--- a/gc.c
+++ b/gc.c
@@ -621,7 +621,6 @@ typedef struct gc_function_map {
void (*config_set)(void *objspace_ptr, VALUE hash);
void (*stress_set)(void *objspace_ptr, VALUE flag);
VALUE (*stress_get)(void *objspace_ptr);
- bool (*checking_shareable)(void *objspace_ptr);
// Object allocation
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size);
size_t (*obj_slot_size)(VALUE obj);
@@ -796,7 +795,6 @@ ruby_modular_gc_init(void)
load_modular_gc_func(config_get);
load_modular_gc_func(stress_set);
load_modular_gc_func(stress_get);
- load_modular_gc_func(checking_shareable);
// Object allocation
load_modular_gc_func(new_obj);
load_modular_gc_func(obj_slot_size);
@@ -877,7 +875,6 @@ ruby_modular_gc_init(void)
# define rb_gc_impl_config_set rb_gc_functions.config_set
# define rb_gc_impl_stress_set rb_gc_functions.stress_set
# define rb_gc_impl_stress_get rb_gc_functions.stress_get
-# define rb_gc_impl_checking_shareable rb_gc_functions.checking_shareable
// Object allocation
# define rb_gc_impl_new_obj rb_gc_functions.new_obj
# define rb_gc_impl_obj_slot_size rb_gc_functions.obj_slot_size
@@ -2808,19 +2805,12 @@ mark_m_tbl(void *objspace, struct rb_id_table *tbl)
}
}
-bool
-rb_gc_checking_shareable(void)
-{
- return rb_gc_impl_checking_shareable(rb_gc_get_objspace());
-}
-
-
static enum rb_id_table_iterator_result
mark_const_entry_i(VALUE value, void *objspace)
{
const rb_const_entry_t *ce = (const rb_const_entry_t *)value;
- if (!rb_gc_impl_checking_shareable(objspace)) {
+ if (!rb_gc_checking_shareable()) {
gc_mark_internal(ce->value);
gc_mark_internal(ce->file); // TODO: ce->file should be shareable?
}
@@ -3085,7 +3075,7 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE box_value, void *a
}
mark_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
- if (!rb_gc_impl_checking_shareable(objspace)) {
+ if (!rb_gc_checking_shareable()) {
// unshareable
gc_mark_internal(RCLASSEXT_FIELDS_OBJ(ext));
}
@@ -3156,7 +3146,7 @@ rb_gc_mark_children(void *objspace, VALUE obj)
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
if (FL_TEST_RAW(obj, FL_SINGLETON) &&
- !rb_gc_impl_checking_shareable(objspace)) {
+ !rb_gc_checking_shareable()) {
gc_mark_internal(RCLASS_ATTACHED_OBJECT(obj));
}
// Continue to the shared T_CLASS/T_MODULE
@@ -5441,6 +5431,68 @@ rb_gc_rp(VALUE obj)
rp(obj);
}
+struct check_shareable_data {
+ VALUE parent;
+ long err_count;
+};
+
+static void
+check_shareable_i(const VALUE child, void *ptr)
+{
+ struct check_shareable_data *data = (struct check_shareable_data *)ptr;
+
+ if (!rb_gc_obj_shareable_p(child)) {
+ fprintf(stderr, "(a) ");
+ rb_gc_rp(data->parent);
+ fprintf(stderr, "(b) ");
+ rb_gc_rp(child);
+ fprintf(stderr, "check_shareable_i: shareable (a) -> unshareable (b)\n");
+
+ data->err_count++;
+ rb_bug("!! violate shareable constraint !!");
+ }
+}
+
+static bool gc_checking_shareable = false;
+
+static void
+gc_verify_shareable(void *objspace, VALUE obj, void *data)
+{
+ // while gc_checking_shareable is true,
+ // other Ractors should not run the GC, until the flag is not local.
+ // TODO: remove VM locking if the flag is Ractor local
+
+ unsigned int lev = RB_GC_VM_LOCK();
+ {
+ gc_checking_shareable = true;
+ rb_objspace_reachable_objects_from(obj, check_shareable_i, (void *)data);
+ gc_checking_shareable = false;
+ }
+ RB_GC_VM_UNLOCK(lev);
+}
+
+// TODO: only one level (non-recursive)
+void
+rb_gc_verify_shareable(VALUE obj)
+{
+ rb_objspace_t *objspace = rb_gc_get_objspace();
+ struct check_shareable_data data = {
+ .parent = obj,
+ .err_count = 0,
+ };
+ gc_verify_shareable(objspace, obj, &data);
+
+ if (data.err_count > 0) {
+ rb_bug("rb_gc_verify_shareable");
+ }
+}
+
+bool
+rb_gc_checking_shareable(void)
+{
+ return gc_checking_shareable;
+}
+
/*
* Document-module: ObjectSpace
*
diff --git a/gc/default/default.c b/gc/default/default.c
index 6045cec598..f84303e02f 100644
--- a/gc/default/default.c
+++ b/gc/default/default.c
@@ -491,7 +491,6 @@ typedef struct rb_objspace {
unsigned int during_minor_gc : 1;
unsigned int during_incremental_marking : 1;
unsigned int measure_gc : 1;
- unsigned int check_shareable : 1;
} flags;
rb_event_flag_t hook_events;
@@ -1460,13 +1459,6 @@ RVALUE_WHITE_P(rb_objspace_t *objspace, VALUE obj)
}
bool
-rb_gc_impl_checking_shareable(void *objspace_ptr)
-{
- rb_objspace_t *objspace = objspace_ptr;
- return objspace->flags.check_shareable;
-}
-
-bool
rb_gc_impl_gc_enabled_p(void *objspace_ptr)
{
rb_objspace_t *objspace = objspace_ptr;
@@ -4980,55 +4972,6 @@ check_children_i(const VALUE child, void *ptr)
}
}
-static void
-check_shareable_i(const VALUE child, void *ptr)
-{
- struct verify_internal_consistency_struct *data = (struct verify_internal_consistency_struct *)ptr;
-
- if (!rb_gc_obj_shareable_p(child)) {
- fprintf(stderr, "(a) ");
- rb_gc_rp(data->parent);
- fprintf(stderr, "(b) ");
- rb_gc_rp(child);
- fprintf(stderr, "check_shareable_i: shareable (a) -> unshareable (b)\n");
-
- data->err_count++;
- rb_bug("!! violate shareable constraint !!");
- }
-}
-
-static void
-gc_verify_shareable(rb_objspace_t *objspace, VALUE obj, void *data)
-{
- // while objspace->flags.check_shareable is true,
- // other Ractors should not run the GC, until the flag is not local.
- // TODO: remove VM locking if the flag is Ractor local
-
- unsigned int lev = RB_GC_VM_LOCK();
- {
- objspace->flags.check_shareable = true;
- rb_objspace_reachable_objects_from(obj, check_shareable_i, (void *)data);
- objspace->flags.check_shareable = false;
- }
- RB_GC_VM_UNLOCK(lev);
-}
-
-// TODO: only one level (non-recursive)
-void
-rb_gc_verify_shareable(VALUE obj)
-{
- rb_objspace_t *objspace = rb_gc_get_objspace();
- struct verify_internal_consistency_struct data = {
- .parent = obj,
- .err_count = 0,
- };
- gc_verify_shareable(objspace, obj, &data);
-
- if (data.err_count > 0) {
- rb_bug("rb_gc_verify_shareable");
- }
-}
-
static int
verify_internal_consistency_i(void *page_start, void *page_end, size_t stride,
struct verify_internal_consistency_struct *data)
@@ -5061,7 +5004,7 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride,
}
if (!is_marking(objspace) && rb_gc_obj_shareable_p(obj)) {
- gc_verify_shareable(objspace, obj, data);
+ rb_gc_verify_shareable(obj);
}
if (is_incremental_marking(objspace)) {
@@ -6716,7 +6659,6 @@ gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_
gc_enter_count(event);
if (RB_UNLIKELY(during_gc != 0)) rb_bug("during_gc != 0");
if (RGENGC_CHECK_MODE >= 3) gc_verify_internal_consistency(objspace);
- GC_ASSERT(!objspace->flags.check_shareable);
during_gc = TRUE;
RUBY_DEBUG_LOG("%s (%s)",gc_enter_event_cstr(event), gc_current_status(objspace));
@@ -6730,7 +6672,6 @@ static inline void
gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_lev)
{
GC_ASSERT(during_gc != 0);
- GC_ASSERT(!objspace->flags.check_shareable);
rb_gc_event_hook(0, RUBY_INTERNAL_EVENT_GC_EXIT);
diff --git a/gc/gc.h b/gc/gc.h
index 89219eb793..f1cf8038e0 100644
--- a/gc/gc.h
+++ b/gc/gc.h
@@ -63,6 +63,7 @@ const char *rb_obj_info(VALUE obj);
size_t rb_obj_memsize_of(VALUE obj);
bool ruby_free_at_exit_p(void);
void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *passing_data);
+void rb_gc_verify_shareable(VALUE);
MODULAR_GC_FN unsigned int rb_gc_vm_lock(const char *file, int line);
MODULAR_GC_FN void rb_gc_vm_unlock(unsigned int lev, const char *file, int line);
diff --git a/gc/gc_impl.h b/gc/gc_impl.h
index 2c05fe6cff..3250483639 100644
--- a/gc/gc_impl.h
+++ b/gc/gc_impl.h
@@ -54,7 +54,6 @@ GC_IMPL_FN void rb_gc_impl_stress_set(void *objspace_ptr, VALUE flag);
GC_IMPL_FN VALUE rb_gc_impl_stress_get(void *objspace_ptr);
GC_IMPL_FN VALUE rb_gc_impl_config_get(void *objspace_ptr);
GC_IMPL_FN void rb_gc_impl_config_set(void *objspace_ptr, VALUE hash);
-GC_IMPL_FN bool rb_gc_impl_checking_shareable(void *objspace_ptr);
// Object allocation
GC_IMPL_FN VALUE rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size);
GC_IMPL_FN size_t rb_gc_impl_obj_slot_size(VALUE obj);
diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c
index 5861f5e70f..9dd3129e01 100644
--- a/gc/mmtk/mmtk.c
+++ b/gc/mmtk/mmtk.c
@@ -1260,12 +1260,6 @@ rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj)
rb_gc_impl_copy_finalizer(objspace_ptr, dest, obj);
}
-bool
-rb_gc_impl_checking_shareable(void *ptr)
-{
- return false;
-}
-
// GC Identification
const char *