From eb08af3874cf2e08ab2cb7f639217cda4251f91c Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 24 Sep 2021 13:11:06 -0400 Subject: [PATCH] init: avoid an undesirable compiler optimization jl_current_task is not constant after this point in the function, so we split the function so that the compiler won't try to optimize it incorrectly (hoisting the JL_GC_PUSH to the top of the function for example). Fixes #42346 --- src/init.c | 11 +++++++++-- src/julia_internal.h | 2 +- src/partr.c | 6 ++++-- src/task.c | 5 +++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/init.c b/src/init.c index 6cf9659d425c5..5fe2d388a40f3 100644 --- a/src/init.c +++ b/src/init.c @@ -628,6 +628,8 @@ static void restore_fp_env(void) } } +static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_task_t *ct); + JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel) { jl_init_timing(); @@ -722,9 +724,14 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel) jl_init_threading(); jl_ptls_t ptls = jl_init_threadtls(0); - jl_init_root_task(ptls, stack_lo, stack_hi); - jl_task_t *ct = jl_current_task; + // warning: this changes `jl_current_task`, so be careful not to call that from this function + jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); + JL_GC_PROMISE_ROOTED(ct); + _finish_julia_init(rel, ptls, ct); +} +static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_task_t *ct) +{ jl_init_threadinginfra(); jl_resolve_sysimg_location(rel); diff --git a/src/julia_internal.h b/src/julia_internal.h index c781a9c981f50..7bc0233fa31a2 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -741,7 +741,7 @@ void jl_init_intrinsic_functions(void); void jl_init_intrinsic_properties(void); void jl_init_tasks(void) JL_GC_DISABLED; void jl_init_stack_limits(int ismaster, void **stack_hi, void **stack_lo); -void jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi); +jl_task_t *jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi); void jl_init_serializer(void); void jl_gc_init(void); void jl_init_uv(void); diff --git a/src/partr.c b/src/partr.c index 467fe29cd3e0f..d4208f660540e 100644 --- a/src/partr.c +++ b/src/partr.c @@ -247,7 +247,9 @@ void jl_threadfun(void *arg) jl_ptls_t ptls = jl_init_threadtls(targ->tid); void *stack_lo, *stack_hi; jl_init_stack_limits(0, &stack_lo, &stack_hi); - jl_init_root_task(ptls, stack_lo, stack_hi); + // warning: this changes `jl_current_task`, so be careful not to call that from this function + jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); + JL_GC_PROMISE_ROOTED(ct); jl_install_thread_signal_handler(ptls); // set up sleep mechanism for this thread @@ -262,7 +264,7 @@ void jl_threadfun(void *arg) free(targ); (void)jl_gc_unsafe_enter(ptls); - jl_finish_task(jl_current_task); // noreturn + jl_finish_task(ct); // noreturn } diff --git a/src/task.c b/src/task.c index ec780c65e5cdf..83b9f048f6462 100644 --- a/src/task.c +++ b/src/task.c @@ -1251,7 +1251,7 @@ static char *jl_alloc_fiber(jl_ucontext_t *t, size_t *ssize, jl_task_t *owner) J #endif // Initialize a root task using the given stack. -void jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi) +jl_task_t *jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi) { assert(ptls->root_task == NULL); // We need `gcstack` in `Task` to allocate Julia objects; *including* the `Task` type. @@ -1327,13 +1327,14 @@ void jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi) #endif if (jl_setjmp(ptls->copy_stack_ctx.uc_mcontext, 0)) start_task(); // sanitizer_finish_switch_fiber is part of start_task - return; + return ct; } ssize = JL_STACK_SIZE; char *stkbuf = jl_alloc_fiber(&ptls->base_ctx, &ssize, NULL); ptls->stackbase = stkbuf + ssize; ptls->stacksize = ssize; #endif + return ct; } JL_DLLEXPORT int jl_is_task_started(jl_task_t *t) JL_NOTSAFEPOINT