Skip to content

Commit abcfb3b

Browse files
gbaralditopolarity
authored andcommitted
Refactor julia initialization by finding and loading the sysimage earlier
1 parent 305479d commit abcfb3b

File tree

4 files changed

+109
-104
lines changed

4 files changed

+109
-104
lines changed

src/init.c

Lines changed: 95 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ static const char *absformat(const char *in)
622622
return out;
623623
}
624624

625-
static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel)
625+
static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel, const char* julia_bindir)
626626
{
627627
// this function resolves the paths in jl_options to absolute file locations as needed
628628
// and it replaces the pointers to `julia_bindir`, `julia_bin`, `image_file`, and output file paths
@@ -642,11 +642,13 @@ static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel)
642642
jl_options.julia_bin = (char*)malloc_s(path_size + 1);
643643
memcpy((char*)jl_options.julia_bin, free_path, path_size);
644644
((char*)jl_options.julia_bin)[path_size] = '\0';
645-
if (!jl_options.julia_bindir) {
645+
if (!julia_bindir) {
646646
jl_options.julia_bindir = getenv("JULIA_BINDIR");
647647
if (!jl_options.julia_bindir) {
648648
jl_options.julia_bindir = dirname(free_path);
649649
}
650+
} else {
651+
jl_options.julia_bindir = julia_bindir;
650652
}
651653
if (jl_options.julia_bindir)
652654
jl_options.julia_bindir = absrealpath(jl_options.julia_bindir, 0);
@@ -721,8 +723,85 @@ static void restore_fp_env(void)
721723
jl_error("Failed to configure floating point environment");
722724
}
723725
}
726+
static NOINLINE void _finish_julia_init(jl_image_buf_t sysimage, jl_ptls_t ptls, jl_task_t *ct)
727+
{
728+
JL_TIMING(JULIA_INIT, JULIA_INIT);
729+
730+
if (sysimage.kind == JL_IMAGE_KIND_SO)
731+
jl_gc_notify_image_load(sysimage.data, sysimage.size);
732+
733+
if (jl_options.cpu_target == NULL)
734+
jl_options.cpu_target = "native";
735+
736+
// Parse image, perform relocations, and init JIT targets, etc.
737+
jl_image_t parsed_image = jl_init_processor_sysimg(sysimage, jl_options.cpu_target);
738+
739+
jl_init_codegen();
740+
jl_init_common_symbols();
741+
742+
if (sysimage.kind != JL_IMAGE_KIND_NONE) {
743+
// Load the .ji or .so sysimage
744+
jl_restore_system_image(&parsed_image, sysimage);
745+
} else {
746+
// No sysimage provided, init a minimal environment
747+
jl_init_types();
748+
jl_global_roots_list = (jl_genericmemory_t*)jl_an_empty_memory_any;
749+
jl_global_roots_keyset = (jl_genericmemory_t*)jl_an_empty_memory_any;
750+
}
751+
752+
jl_init_flisp();
753+
jl_init_serializer();
754+
755+
if (sysimage.kind == JL_IMAGE_KIND_NONE) {
756+
jl_top_module = jl_core_module;
757+
jl_init_intrinsic_functions();
758+
jl_init_primitives();
759+
jl_init_main_module();
760+
jl_load(jl_core_module, "boot.jl");
761+
jl_current_task->world_age = jl_atomic_load_acquire(&jl_world_counter);
762+
post_boot_hooks();
763+
}
764+
765+
if (jl_base_module == NULL) {
766+
// nthreads > 1 requires code in Base
767+
jl_atomic_store_relaxed(&jl_n_threads, 1);
768+
jl_n_markthreads = 0;
769+
jl_n_sweepthreads = 0;
770+
jl_n_gcthreads = 0;
771+
jl_n_threads_per_pool[JL_THREADPOOL_ID_INTERACTIVE] = 0;
772+
jl_n_threads_per_pool[JL_THREADPOOL_ID_DEFAULT] = 1;
773+
} else {
774+
jl_current_task->world_age = jl_atomic_load_acquire(&jl_world_counter);
775+
post_image_load_hooks();
776+
}
777+
jl_start_threads();
778+
jl_start_gc_threads();
779+
uv_barrier_wait(&thread_init_done);
780+
781+
jl_gc_enable(1);
782+
783+
if ((sysimage.kind != JL_IMAGE_KIND_NONE) &&
784+
(!jl_generating_output() || jl_options.incremental) && jl_module_init_order) {
785+
jl_array_t *init_order = jl_module_init_order;
786+
JL_GC_PUSH1(&init_order);
787+
jl_module_init_order = NULL;
788+
int i, l = jl_array_nrows(init_order);
789+
for (i = 0; i < l; i++) {
790+
jl_value_t *mod = jl_array_ptr_ref(init_order, i);
791+
jl_module_run_initializer((jl_module_t*)mod);
792+
}
793+
JL_GC_POP();
794+
}
795+
796+
if (jl_options.trim) {
797+
jl_entrypoint_mis = (arraylist_t *)malloc_s(sizeof(arraylist_t));
798+
arraylist_new(jl_entrypoint_mis, 0);
799+
}
800+
801+
if (jl_options.handle_signals == JL_OPTIONS_HANDLE_SIGNALS_ON)
802+
jl_install_sigint_handler();
803+
}
724804

725-
static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_task_t *ct);
726805

727806
JL_DLLEXPORT int jl_default_debug_info_kind;
728807
JL_DLLEXPORT jl_cgparams_t jl_default_cgparams = {
@@ -750,7 +829,7 @@ static void init_global_mutexes(void) {
750829
JL_MUTEX_INIT(&profile_show_peek_cond_lock, "profile_show_peek_cond_lock");
751830
}
752831

753-
JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
832+
static void julia_init(jl_image_buf_t sysimage)
754833
{
755834
// initialize many things, in no particular order
756835
// but generally running from simple platform things to optional
@@ -860,96 +939,27 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
860939
jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi);
861940
#pragma GCC diagnostic pop
862941
JL_GC_PROMISE_ROOTED(ct);
863-
_finish_julia_init(rel, ptls, ct);
942+
_finish_julia_init(sysimage, ptls, ct);
864943
}
865944

866-
static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_task_t *ct)
867-
{
868-
JL_TIMING(JULIA_INIT, JULIA_INIT);
869-
jl_resolve_sysimg_location(rel);
945+
946+
// This function is responsible for loading the image and initializing paths in jl_options
947+
JL_DLLEXPORT void jl_load_image_and_init(JL_IMAGE_SEARCH rel, const char* julia_bindir, void *handle) {
948+
libsupport_init();
949+
950+
jl_resolve_sysimg_location(rel, julia_bindir);
870951

871952
// loads sysimg if available, and conditionally sets jl_options.cpu_target
872953
jl_image_buf_t sysimage = { JL_IMAGE_KIND_NONE };
873-
if (rel == JL_IMAGE_IN_MEMORY) {
954+
if (handle != NULL) {
955+
sysimage = jl_set_sysimg_so(handle);
956+
} else if (rel == JL_IMAGE_IN_MEMORY) {
874957
sysimage = jl_set_sysimg_so(jl_exe_handle);
875958
jl_options.image_file = jl_options.julia_bin;
876-
}
877-
else if (jl_options.image_file)
959+
} else if (jl_options.image_file)
878960
sysimage = jl_preload_sysimg(jl_options.image_file);
879961

880-
if (sysimage.kind == JL_IMAGE_KIND_SO)
881-
jl_gc_notify_image_load(sysimage.data, sysimage.size);
882-
883-
if (jl_options.cpu_target == NULL)
884-
jl_options.cpu_target = "native";
885-
886-
// Parse image, perform relocations, and init JIT targets, etc.
887-
jl_image_t parsed_image = jl_init_processor_sysimg(sysimage, jl_options.cpu_target);
888-
889-
jl_init_codegen();
890-
jl_init_common_symbols();
891-
892-
if (sysimage.kind != JL_IMAGE_KIND_NONE) {
893-
// Load the .ji or .so sysimage
894-
jl_restore_system_image(&parsed_image, sysimage);
895-
} else {
896-
// No sysimage provided, init a minimal environment
897-
jl_init_types();
898-
jl_global_roots_list = (jl_genericmemory_t*)jl_an_empty_memory_any;
899-
jl_global_roots_keyset = (jl_genericmemory_t*)jl_an_empty_memory_any;
900-
}
901-
902-
jl_init_flisp();
903-
jl_init_serializer();
904-
905-
if (sysimage.kind == JL_IMAGE_KIND_NONE) {
906-
jl_top_module = jl_core_module;
907-
jl_init_intrinsic_functions();
908-
jl_init_primitives();
909-
jl_init_main_module();
910-
jl_load(jl_core_module, "boot.jl");
911-
jl_current_task->world_age = jl_atomic_load_acquire(&jl_world_counter);
912-
post_boot_hooks();
913-
}
914-
915-
if (jl_base_module == NULL) {
916-
// nthreads > 1 requires code in Base
917-
jl_atomic_store_relaxed(&jl_n_threads, 1);
918-
jl_n_markthreads = 0;
919-
jl_n_sweepthreads = 0;
920-
jl_n_gcthreads = 0;
921-
jl_n_threads_per_pool[JL_THREADPOOL_ID_INTERACTIVE] = 0;
922-
jl_n_threads_per_pool[JL_THREADPOOL_ID_DEFAULT] = 1;
923-
} else {
924-
jl_current_task->world_age = jl_atomic_load_acquire(&jl_world_counter);
925-
post_image_load_hooks();
926-
}
927-
jl_start_threads();
928-
jl_start_gc_threads();
929-
uv_barrier_wait(&thread_init_done);
930-
931-
jl_gc_enable(1);
932-
933-
if ((sysimage.kind != JL_IMAGE_KIND_NONE) &&
934-
(!jl_generating_output() || jl_options.incremental) && jl_module_init_order) {
935-
jl_array_t *init_order = jl_module_init_order;
936-
JL_GC_PUSH1(&init_order);
937-
jl_module_init_order = NULL;
938-
int i, l = jl_array_nrows(init_order);
939-
for (i = 0; i < l; i++) {
940-
jl_value_t *mod = jl_array_ptr_ref(init_order, i);
941-
jl_module_run_initializer((jl_module_t*)mod);
942-
}
943-
JL_GC_POP();
944-
}
945-
946-
if (jl_options.trim) {
947-
jl_entrypoint_mis = (arraylist_t *)malloc_s(sizeof(arraylist_t));
948-
arraylist_new(jl_entrypoint_mis, 0);
949-
}
950-
951-
if (jl_options.handle_signals == JL_OPTIONS_HANDLE_SIGNALS_ON)
952-
jl_install_sigint_handler();
962+
julia_init(sysimage);
953963
}
954964

955965
#ifdef __cplusplus

src/jlapi.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ JL_DLLEXPORT void jl_set_ARGS(int argc, char **argv)
6868
}
6969
}
7070

71+
JL_DLLEXPORT void jl_init_with_handle(void *handle) {
72+
if (jl_is_initialized())
73+
return;
74+
const char *image_path = jl_pathname_for_handle(handle);
75+
jl_enter_threaded_region(); // This should maybe be behind a lock, but it's harmless if done twice
76+
jl_options.image_file = image_path;
77+
jl_load_image_and_init(JL_IMAGE_JULIA_HOME, NULL, handle);
78+
jl_exception_clear();
79+
}
7180
/**
7281
* @brief Initialize Julia with a specified system image file.
7382
*
@@ -87,23 +96,11 @@ JL_DLLEXPORT void jl_init_with_image(const char *julia_bindir,
8796
{
8897
if (jl_is_initialized())
8998
return;
90-
libsupport_init();
91-
if (julia_bindir) {
92-
jl_options.julia_bindir = julia_bindir;
93-
} else {
94-
#ifdef _OS_WINDOWS_
95-
jl_options.julia_bindir = strdup(jl_get_libdir());
96-
#else
97-
int written = asprintf((char**)&jl_options.julia_bindir, "%s" PATHSEPSTRING ".." PATHSEPSTRING "%s", jl_get_libdir(), "bin");
98-
if (written < 0)
99-
abort(); // unexpected: memory allocation failed
100-
#endif
101-
}
10299
if (image_path != NULL)
103100
jl_options.image_file = image_path;
104101
else
105102
jl_options.image_file = jl_get_default_sysimg_path();
106-
julia_init(JL_IMAGE_JULIA_HOME);
103+
jl_load_image_and_init(JL_IMAGE_JULIA_HOME, julia_bindir, NULL);
107104
jl_exception_clear();
108105
}
109106

@@ -1100,8 +1097,7 @@ JL_DLLEXPORT int jl_repl_entrypoint(int argc, char *argv[])
11001097
#endif
11011098
jl_error("Failed to self-execute");
11021099
}
1103-
1104-
julia_init(jl_options.image_file_specified ? JL_IMAGE_CWD : JL_IMAGE_JULIA_HOME);
1100+
jl_load_image_and_init(jl_options.image_file_specified ? JL_IMAGE_CWD : JL_IMAGE_JULIA_HOME, NULL, NULL);
11051101
if (lisp_prompt) {
11061102
jl_current_task->world_age = jl_get_world_counter();
11071103
jl_lisp_prompt();

src/julia.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2223,10 +2223,11 @@ struct _jl_image_t;
22232223
typedef struct _jl_image_t jl_image_t;
22242224

22252225
JL_DLLIMPORT const char *jl_get_libdir(void);
2226-
JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel);
22272226
JL_DLLEXPORT void jl_init(void);
22282227
JL_DLLEXPORT void jl_init_with_image(const char *julia_bindir,
22292228
const char *image_path);
2229+
JL_DLLEXPORT void jl_load_image_and_init(JL_IMAGE_SEARCH rel, const char* julia_bindir, void *handle);
2230+
JL_DLLEXPORT void jl_init_with_handle(void *handle);
22302231
JL_DLLEXPORT const char *jl_get_default_sysimg_path(void);
22312232
JL_DLLEXPORT int jl_is_initialized(void);
22322233
JL_DLLEXPORT void jl_atexit_hook(int status);

src/threading.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,7 @@ JL_DLLEXPORT jl_gcframe_t **jl_autoinit_and_adopt_thread(void)
461461
" (this should not happen, please file a bug report)\n");
462462
exit(1);
463463
}
464-
const char *image_path = jl_pathname_for_handle(handle);
465-
jl_enter_threaded_region(); // This should maybe be behind a lock, but it's harmless if done twice
466-
jl_init_with_image(NULL, image_path);
464+
jl_init_with_handle(handle);
467465
return &jl_get_current_task()->gcstack;
468466
}
469467

0 commit comments

Comments
 (0)