summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-10-19 11:16:02 -0400
committerPeter Zhu <peter@peterzhu.ca>2025-10-21 18:42:17 -0400
commitcd42096f5a8a15573ccb1e8bcd83872877907541 (patch)
tree5a071ae5d1e3b6febecf00fa3f376e324e6cc96b
parent0cc4819f2461c8080a2e50b9ab7cbb16798c39ce (diff)
Move rb_class_classext_free to class.c
-rw-r--r--class.c54
-rw-r--r--gc.c40
-rw-r--r--internal/class.h3
3 files changed, 59 insertions, 38 deletions
diff --git a/class.c b/class.c
index 77f2fba516..2b78d73378 100644
--- a/class.c
+++ b/class.c
@@ -79,6 +79,60 @@
#define METACLASS_OF(k) RBASIC(k)->klass
#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
+static enum rb_id_table_iterator_result
+cvar_table_free_i(VALUE value, void *ctx)
+{
+ xfree((void *)value);
+ return ID_TABLE_CONTINUE;
+}
+
+void
+rb_class_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime)
+{
+ struct rb_id_table *tbl;
+
+ rb_id_table_free(RCLASSEXT_M_TBL(ext));
+
+ if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
+ rb_free_const_table(tbl);
+ }
+
+ if ((tbl = RCLASSEXT_CVC_TBL(ext)) != NULL) {
+ rb_id_table_foreach_values(tbl, cvar_table_free_i, NULL);
+ rb_id_table_free(tbl);
+ }
+
+ rb_class_classext_free_subclasses(ext, klass);
+
+ if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
+ RUBY_ASSERT(is_prime); // superclasses should only be used on prime
+ xfree(RCLASSEXT_SUPERCLASSES(ext));
+ }
+
+ if (!is_prime) { // the prime classext will be freed with RClass
+ xfree(ext);
+ }
+}
+
+void
+rb_iclass_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime)
+{
+ if (RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext)) {
+ /* Method table is not shared for origin iclasses of classes */
+ rb_id_table_free(RCLASSEXT_M_TBL(ext));
+ }
+
+ if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
+ rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
+ }
+
+ rb_class_classext_free_subclasses(ext, klass);
+
+ if (!is_prime) { // the prime classext will be freed with RClass
+ xfree(ext);
+ }
+}
+
RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
struct duplicate_id_tbl_data {
diff --git a/gc.c b/gc.c
index 42625e1004..897447c808 100644
--- a/gc.c
+++ b/gc.c
@@ -1160,13 +1160,6 @@ rb_objspace_data_type_name(VALUE obj)
}
}
-static enum rb_id_table_iterator_result
-cvar_table_free_i(VALUE value, void *ctx)
-{
- xfree((void *)value);
- return ID_TABLE_CONTINUE;
-}
-
static void
io_fptr_finalize(void *fptr)
{
@@ -1233,26 +1226,9 @@ struct classext_foreach_args {
static void
classext_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
{
- struct rb_id_table *tbl;
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
- rb_id_table_free(RCLASSEXT_M_TBL(ext));
-
- if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
- rb_free_const_table(tbl);
- }
- if ((tbl = RCLASSEXT_CVC_TBL(ext)) != NULL) {
- rb_id_table_foreach_values(tbl, cvar_table_free_i, NULL);
- rb_id_table_free(tbl);
- }
- rb_class_classext_free_subclasses(ext, args->klass);
- if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
- RUBY_ASSERT(is_prime); // superclasses should only be used on prime
- xfree(RCLASSEXT_SUPERCLASSES(ext));
- }
- if (!is_prime) { // the prime classext will be freed with RClass
- xfree(ext);
- }
+ rb_class_classext_free(args->klass, ext, is_prime);
}
static void
@@ -1260,19 +1236,7 @@ classext_iclass_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *a
{
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
- if (RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext)) {
- /* Method table is not shared for origin iclasses of classes */
- rb_id_table_free(RCLASSEXT_M_TBL(ext));
- }
- if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
- rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
- }
-
- rb_class_classext_free_subclasses(ext, args->klass);
-
- if (!is_prime) { // the prime classext will be freed with RClass
- xfree(ext);
- }
+ rb_iclass_classext_free(args->klass, ext, is_prime);
}
bool
diff --git a/internal/class.h b/internal/class.h
index f5c5142b45..9fc6d243e6 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -317,6 +317,9 @@ RCLASS_SET_CLASSEXT_TBL(VALUE klass, st_table *tbl)
rb_classext_t * rb_class_duplicate_classext(rb_classext_t *orig, VALUE obj, const rb_namespace_t *ns);
void rb_class_ensure_writable(VALUE obj);
+void rb_class_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime);
+void rb_iclass_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime);
+
static inline int
RCLASS_SET_NAMESPACE_CLASSEXT(VALUE obj, const rb_namespace_t *ns, rb_classext_t *ext)
{