diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2026-01-31 08:53:48 +0100 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2026-01-31 10:35:48 +0100 |
| commit | bd6fa7f5cca426901bc9162724966339440bc6cb (patch) | |
| tree | 57363875f68945549cb9bc47b7e63950b1d5c6b0 | |
| parent | db52e98520349e2bfcd471a0c2f96d696a4f7498 (diff) | |
ruby_xfree: reject memory allocated by ruby_mimalloc
| -rw-r--r-- | cont.c | 9 | ||||
| -rw-r--r-- | gc/default/default.c | 4 | ||||
| -rw-r--r-- | ractor.c | 8 | ||||
| -rw-r--r-- | ractor_core.h | 1 | ||||
| -rw-r--r-- | vm.c | 8 | ||||
| -rw-r--r-- | vm_core.h | 1 | ||||
| -rw-r--r-- | vm_trace.c | 2 |
7 files changed, 29 insertions, 4 deletions
@@ -215,6 +215,7 @@ typedef struct rb_context_struct { enum context_type type; int argc; int kw_splat; + bool root; VALUE self; VALUE value; @@ -1102,7 +1103,12 @@ cont_free(void *ptr) VM_ASSERT(cont->jit_cont != NULL); jit_cont_free(cont->jit_cont); /* free rb_cont_t or rb_fiber_t */ - ruby_xfree(ptr); + if (cont->root) { + ruby_mimfree(ptr); + } + else { + ruby_xfree(ptr); + } RUBY_FREE_LEAVE("cont"); } @@ -2574,6 +2580,7 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th) } fiber->cont.type = FIBER_CONTEXT; + fiber->cont.root = true; fiber->cont.saved_ec.fiber_ptr = fiber; fiber->cont.saved_ec.serial = next_ec_serial(th->ractor); fiber->cont.saved_ec.thread_ptr = th; diff --git a/gc/default/default.c b/gc/default/default.c index 90232c7618..bfddb08ea5 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -8279,6 +8279,10 @@ rb_gc_impl_free(void *objspace_ptr, void *ptr, size_t old_size) #if CALC_EXACT_MALLOC_SIZE struct malloc_obj_info *info = (struct malloc_obj_info *)ptr - 1; #if VERIFY_FREE_SIZE + if (!info->size) { + rb_bug("buffer %p has no recorded size. Was it allocated with ruby_mimalloc? If so it should be freed with ruby_mimfree", ptr); + } + if (old_size && (old_size + sizeof(struct malloc_obj_info)) != info->size) { rb_bug("buffer %p freed with old_size=%lu, but was allocated with size=%lu", ptr, old_size, info->size - sizeof(struct malloc_obj_info)); } @@ -298,7 +298,12 @@ ractor_free(void *ptr) } ractor_sync_free(r); - ruby_xfree(r); + if (r->main_ractor) { + ruby_mimfree(r); + } + else { + ruby_xfree(r); + } } static size_t @@ -478,6 +483,7 @@ rb_ractor_main_alloc(void) r->pub.self = Qnil; r->newobj_cache = rb_gc_ractor_cache_alloc(r); r->next_ec_serial = 1; + r->main_ractor = true; ruby_single_main_ractor = r; return r; diff --git a/ractor_core.h b/ractor_core.h index d112ff8724..d795136b70 100644 --- a/ractor_core.h +++ b/ractor_core.h @@ -104,6 +104,7 @@ struct rb_ractor_struct { VALUE debug; bool malloc_gc_disabled; + bool main_ractor; void *newobj_cache; }; // rb_ractor_t is defined in vm_core.h @@ -3821,7 +3821,12 @@ thread_free(void *ptr) else { // ruby_xfree(th->nt); // TODO: MN system collect nt, but without MN system it should be freed here. - ruby_xfree(th); + if (th->main_thread) { + ruby_mimfree(th); + } + else { + ruby_xfree(th); + } } RUBY_FREE_LEAVE("thread"); @@ -4594,6 +4599,7 @@ Init_BareVM(void) vm->global_hooks.type = hook_list_type_global; // setup main thread + th->main_thread = 1; th->nt = ZALLOC(struct rb_native_thread); th->vm = vm; th->ractor = vm->ractor.main_ractor = rb_ractor_main_alloc(); @@ -1152,6 +1152,7 @@ typedef struct rb_thread_struct { BITFIELD(enum rb_thread_status, status, 2); /* bit flags */ + unsigned int main_thread : 1; unsigned int has_dedicated_nt : 1; unsigned int to_kill : 1; unsigned int abort_on_exception: 1; diff --git a/vm_trace.c b/vm_trace.c index 0090541275..11cf7f55b5 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -1901,7 +1901,7 @@ void rb_vm_postponed_job_free(void) { rb_vm_t *vm = GET_VM(); - ruby_xfree(vm->postponed_job_queue); + ruby_mimfree(vm->postponed_job_queue); vm->postponed_job_queue = NULL; } |
