core: the first environment is statically allocated

This is to avoid circularity between the first environment (and interrupts) and
the garbage collector.
This commit is contained in:
Daniel Kochmański 2025-03-27 14:26:57 +01:00
parent 09ebfb47dd
commit f49cc7f3fd
3 changed files with 18 additions and 32 deletions

View file

@ -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);
}
}
}

View file

@ -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);
/*

View file

@ -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;