From f49cc7f3fd3db62448959c0ffbf8a9fe0519efe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Thu, 27 Mar 2025 14:26:57 +0100 Subject: [PATCH] core: the first environment is statically allocated This is to avoid circularity between the first environment (and interrupts) and the garbage collector. --- src/c/alloc_2.d | 23 +++++++++-------------- src/c/main.d | 26 ++++++++------------------ src/h/external.h | 1 + 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d index c52f8f209..ea44b057c 100644 --- a/src/c/alloc_2.d +++ b/src/c/alloc_2.d @@ -1183,22 +1183,17 @@ ecl_mark_env(struct cl_env_struct *env) static void stacks_scanner() { - cl_env_ptr the_env = ecl_process_env_unsafe(); - cl_object l; - l = cl_core.libraries; - if (l) { - for (; l != ECL_NIL; l = ECL_CONS_CDR(l)) { - cl_object dll = ECL_CONS_CAR(l); - if (dll->cblock.locked) { - GC_push_conditional((void *)dll, (void *)(&dll->cblock + 1), 1); - GC_set_mark_bit((void *)dll); - } + cl_object l = cl_core.libraries; + loop_for_on_unsafe(l) { + cl_object dll = ECL_CONS_CAR(l); + if (dll->cblock.locked) { + GC_push_conditional((void *)dll, (void *)(&dll->cblock + 1), 1); + GC_set_mark_bit((void *)dll); } - } + } end_loop_for_on_unsafe(l); GC_push_all((void *)(&cl_core), (void *)(&cl_core + 1)); GC_push_all((void *)cl_symbols, (void *)(cl_symbols + cl_num_symbols_in_core)); - if (the_env != NULL) - ecl_mark_env(the_env); + ecl_mark_env(cl_core.first_env); #ifdef ECL_THREADS l = cl_core.processes; if (l != OBJNULL) { @@ -1207,7 +1202,7 @@ stacks_scanner() cl_object process = l->vector.self.t[i]; if (!Null(process)) { cl_env_ptr env = process->process.env; - if (env && (env != the_env)) ecl_mark_env(env); + if (env && (env != cl_core.first_env)) ecl_mark_env(env); } } } diff --git a/src/c/main.d b/src/c/main.d index e7b48ec53..13915a155 100644 --- a/src/c/main.d +++ b/src/c/main.d @@ -48,10 +48,8 @@ /******************************* EXPORTS ******************************/ -#if !defined(ECL_THREADS) -cl_env_ptr cl_env_p = NULL; -#endif const char *ecl_self; +static struct cl_env_struct first_env; /************************ GLOBAL INITIALIZATION ***********************/ @@ -248,20 +246,13 @@ _ecl_alloc_env(cl_env_ptr parent) ecl_internal_error("Unable to allocate environment structure."); #else # if defined(ECL_USE_GUARD_PAGE) - output = VirtualAlloc(0, sizeof(*output), MEM_COMMIT, - PAGE_READWRITE); + output = VirtualAlloc(0, sizeof(*output), MEM_COMMIT, PAGE_READWRITE); if (output == NULL) ecl_internal_error("Unable to allocate environment structure."); # else - static struct cl_env_struct first_env; - if (!ecl_option_values[ECL_OPT_BOOTED]) { - /* We have not set up any environment. Hence, we cannot call ecl_alloc() - * because it will need to stop interrupts and currently we rely on - * the environment for that */ - output = ecl_alloc_unprotected(sizeof(*output)); - } else { - output = ecl_alloc(sizeof(*output)); - } + output = ecl_alloc(sizeof(*output)); + if (output == NULL) + ecl_internal_error("Unable to allocate environment structure."); # endif #endif { @@ -270,9 +261,7 @@ _ecl_alloc_env(cl_env_ptr parent) output->default_sigmask = 0; } else if (parent) { output->default_sigmask = ecl_alloc_atomic(bytes); - memcpy(output->default_sigmask, - parent->default_sigmask, - bytes); + memcpy(output->default_sigmask, parent->default_sigmask, bytes); } else { output->default_sigmask = cl_core.default_sigmask; } @@ -414,6 +403,7 @@ struct cl_core_struct cl_core = { .system_properties = ECL_NIL, + .first_env = &first_env, #ifdef ECL_THREADS .processes = ECL_NIL, #endif @@ -501,7 +491,7 @@ cl_boot(int argc, char **argv) init_unixint(0); init_alloc(); GC_disable(); - env = _ecl_alloc_env(0); + env = cl_core.first_env; init_threads(env); /* diff --git a/src/h/external.h b/src/h/external.h index a4161f577..959970b88 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -221,6 +221,7 @@ struct cl_core_struct { cl_object system_properties; + cl_env_ptr first_env; #ifdef ECL_THREADS cl_object processes; ecl_mutex_t processes_lock;