summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2026-04-08 13:10:50 +0200
committerJean Boussier <jean.boussier@gmail.com>2026-04-08 21:00:02 +0200
commit5cf6c842e573a55dbc89619e939fd7fa8a203b87 (patch)
tree6b0ea71f71fa784374074bf5116e4c9d46b8e623
parent30e31488257ae7697190cfe8649af3077a8eef5d (diff)
rb_gc_obj_needs_cleanup_p: skip sweep for most imemo/fields
There is only two rare cases where they need to be sweeped: - If they are so large that they're heap allocated. - If they have an object_id (and id2ref_tbl exist but we can't check that here)
-rw-r--r--gc.c30
-rw-r--r--internal/imemo.h26
2 files changed, 29 insertions, 27 deletions
diff --git a/gc.c b/gc.c
index f05b1a6913..3cf3bdebce 100644
--- a/gc.c
+++ b/gc.c
@@ -1291,6 +1291,34 @@ rb_gc_handle_weak_references(VALUE obj)
}
}
+static inline bool
+rb_gc_imemo_needs_cleanup_p(VALUE obj)
+{
+ switch (imemo_type(obj)) {
+ case imemo_constcache:
+ case imemo_cref:
+ case imemo_ifunc:
+ case imemo_memo:
+ case imemo_svar:
+ case imemo_callcache:
+ case imemo_throw_data:
+ return false;
+
+ case imemo_env:
+ case imemo_ment:
+ case imemo_iseq:
+ case imemo_callinfo:
+ return true;
+
+ case imemo_tmpbuf:
+ return ((rb_imemo_tmpbuf_t *)obj)->ptr != NULL;
+
+ case imemo_fields:
+ return FL_TEST_RAW(obj, OBJ_FIELD_HEAP) || (id2ref_tbl && rb_shape_obj_has_id(obj));
+ }
+ UNREACHABLE_RETURN(true);
+}
+
/*
* Returns true if the object requires a full rb_gc_obj_free() call during sweep,
* false if it can be freed quickly without calling destructors or cleanup.
@@ -1313,7 +1341,7 @@ rb_gc_obj_needs_cleanup_p(VALUE obj)
switch (flags & RUBY_T_MASK) {
case T_IMEMO:
- return rb_imemo_needs_cleanup_p(obj);
+ return rb_gc_imemo_needs_cleanup_p(obj);
case T_DATA:
case T_OBJECT:
diff --git a/internal/imemo.h b/internal/imemo.h
index 4f2c4ebfbf..e48832b4e5 100644
--- a/internal/imemo.h
+++ b/internal/imemo.h
@@ -292,30 +292,4 @@ rb_imemo_fields_complex_tbl(VALUE fields_obj)
return IMEMO_OBJ_FIELDS(fields_obj)->as.complex.table;
}
-static inline bool
-rb_imemo_needs_cleanup_p(VALUE obj)
-{
- switch (imemo_type(obj)) {
- case imemo_constcache:
- case imemo_cref:
- case imemo_ifunc:
- case imemo_memo:
- case imemo_svar:
- case imemo_callcache:
- case imemo_throw_data:
- return false;
-
- case imemo_env:
- case imemo_ment:
- case imemo_iseq:
- case imemo_callinfo:
- case imemo_fields:
- return true;
-
- case imemo_tmpbuf:
- return ((rb_imemo_tmpbuf_t *)obj)->ptr != NULL;
- }
- UNREACHABLE_RETURN(true);
-}
-
#endif /* INTERNAL_IMEMO_H */