diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2026-04-08 13:10:50 +0200 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2026-04-08 21:00:02 +0200 |
| commit | 5cf6c842e573a55dbc89619e939fd7fa8a203b87 (patch) | |
| tree | 6b0ea71f71fa784374074bf5116e4c9d46b8e623 | |
| parent | 30e31488257ae7697190cfe8649af3077a8eef5d (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.c | 30 | ||||
| -rw-r--r-- | internal/imemo.h | 26 |
2 files changed, 29 insertions, 27 deletions
@@ -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 */ |
