aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorAdam Hess <adamhess1991@gmail.com>2023-10-12 11:15:53 -0700
committerPeter Zhu <peter@peterzhu.ca>2023-12-07 15:52:35 -0500
commit6816e8efcff3be75f8020cd1b0ea57d3cd664bbc (patch)
tree8f8484b955ba25e9df6a2038db0f156e7cbf71e4 /gc.c
parentb361a800c22e0248bf126d77e96a7bd4f9c34d1b (diff)
downloadruby-6816e8efcff3be75f8020cd1b0ea57d3cd664bbc.tar.gz
Free everything at shutdown
when the RUBY_FREE_ON_SHUTDOWN environment variable is set, manually free memory at shutdown. Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org> Co-authored-by: Peter Zhu <peter@peterzhu.ca>
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/gc.c b/gc.c
index 08e4a2cd3e..ce5ae34dc8 100644
--- a/gc.c
+++ b/gc.c
@@ -4583,6 +4583,35 @@ force_chain_object(st_data_t key, st_data_t val, st_data_t arg)
bool rb_obj_is_main_ractor(VALUE gv);
void
+rb_objspace_free_objects(rb_objspace_t *objspace)
+{
+ for (size_t i = 0; i < heap_allocated_pages; i++) {
+ struct heap_page *page = heap_pages_sorted[i];
+ short stride = page->slot_size;
+
+ uintptr_t p = (uintptr_t)page->start;
+ uintptr_t pend = p + page->total_slots * stride;
+ for (; p < pend; p += stride) {
+ VALUE vp = (VALUE)p;
+ switch (BUILTIN_TYPE(vp)) {
+ case T_DATA: {
+ if (rb_obj_is_mutex(vp) || rb_obj_is_thread(vp)) {
+ rb_data_free(objspace, vp);
+ }
+ break;
+ }
+ case T_ARRAY:
+ obj_free(objspace, vp);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+
+void
rb_objspace_call_finalizer(rb_objspace_t *objspace)
{
size_t i;
@@ -4648,7 +4677,14 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
make_io_zombie(objspace, vp);
}
break;
+ case T_SYMBOL:
+ case T_ARRAY:
+ case T_NONE:
+ break;
default:
+ if (rb_free_on_exit) {
+ obj_free(objspace, vp);
+ }
break;
}
if (poisoned) {