Skip to content

Commit 37a7541

Browse files
authored
Make trimmed binaries initialize on first call (#58141)
1 parent 860188f commit 37a7541

File tree

4 files changed

+24
-38
lines changed

4 files changed

+24
-38
lines changed

contrib/juliac.jl

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ allflags = Base.shell_split(allflags)
8888
rpath = get_rpath(; relative = relative_rpath)
8989
rpath = Base.shell_split(rpath)
9090
tmpdir = mktempdir(cleanup=false)
91-
initsrc_path = joinpath(tmpdir, "init.c")
92-
init_path = joinpath(tmpdir, "init.a")
9391
img_path = joinpath(tmpdir, "img.a")
9492
bc_path = joinpath(tmpdir, "img-bc.a")
9593

@@ -122,19 +120,6 @@ function compile_products(enable_trim::Bool)
122120
exit(1)
123121
end
124122

125-
# Compile the initialization code
126-
open(initsrc_path, "w") do io
127-
print(io, """
128-
#include <julia.h>
129-
__attribute__((constructor)) void static_init(void) {
130-
if (jl_is_initialized())
131-
return;
132-
julia_init(JL_IMAGE_IN_MEMORY);
133-
jl_exception_clear();
134-
}
135-
""")
136-
end
137-
run(`cc $(cflags) -g -c -o $init_path $initsrc_path`)
138123
end
139124

140125
function link_products()
@@ -150,11 +135,11 @@ function link_products()
150135
julia_libs = Base.shell_split(Base.isdebugbuild() ? "-ljulia-debug -ljulia-internal-debug" : "-ljulia -ljulia-internal")
151136
try
152137
if output_type == "--output-lib"
153-
cmd2 = `cc $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $init_path $(julia_libs)`
138+
cmd2 = `cc $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)`
154139
elseif output_type == "--output-sysimage"
155140
cmd2 = `cc $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)`
156141
else
157-
cmd2 = `cc $(allflags) $(rpath) -o $outname -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $init_path $(julia_libs)`
142+
cmd2 = `cc $(allflags) $(rpath) -o $outname -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)`
158143
end
159144
verbose && println("Running: $cmd2")
160145
run(cmd2)

src/jlapi.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,17 @@ JL_DLLEXPORT void jl_init_with_image(const char *julia_bindir,
8888
if (jl_is_initialized())
8989
return;
9090
libsupport_init();
91-
jl_options.julia_bindir = julia_bindir;
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+
}
92102
if (image_path != NULL)
93103
jl_options.image_file = image_path;
94104
else
@@ -105,18 +115,7 @@ JL_DLLEXPORT void jl_init_with_image(const char *julia_bindir,
105115
*/
106116
JL_DLLEXPORT void jl_init(void)
107117
{
108-
char *libbindir = NULL;
109-
#ifdef _OS_WINDOWS_
110-
libbindir = strdup(jl_get_libdir());
111-
#else
112-
(void)asprintf(&libbindir, "%s" PATHSEPSTRING ".." PATHSEPSTRING "%s", jl_get_libdir(), "bin");
113-
#endif
114-
if (!libbindir) {
115-
printf("jl_init unable to find libjulia!\n");
116-
abort();
117-
}
118-
jl_init_with_image(libbindir, jl_get_default_sysimg_path());
119-
free(libbindir);
118+
jl_init_with_image(NULL, jl_get_default_sysimg_path());
120119
}
121120

122121
static void _jl_exception_clear(jl_task_t *ct) JL_NOTSAFEPOINT

src/julia_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#ifndef JL_INTERNAL_H
44
#define JL_INTERNAL_H
55

6+
#include "dtypes.h"
67
#include "options.h"
78
#include "julia_assert.h"
89
#include "julia_locks.h"
@@ -192,6 +193,8 @@ void JL_UV_LOCK(void);
192193
extern _Atomic(unsigned) _threadedregion;
193194
extern _Atomic(uint16_t) io_loop_tid;
194195

196+
JL_DLLEXPORT void jl_enter_threaded_region(void);
197+
JL_DLLEXPORT void jl_exit_threaded_region(void);
195198
int jl_running_under_rr(int recheck) JL_NOTSAFEPOINT;
196199

197200
//--------------------------------------------------

src/threading.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
// This file is a part of Julia. License is MIT: https://julialang.org/license
2-
32
#include <stdint.h>
43
#include <stdio.h>
54
#include <stdlib.h>
65
#include <string.h>
76
#include <inttypes.h>
8-
97
#include "julia.h"
108
#include "julia_internal.h"
119
#include "julia_assert.h"
@@ -457,15 +455,16 @@ JL_DLLEXPORT jl_gcframe_t **jl_autoinit_and_adopt_thread(void)
457455
{
458456
if (!jl_is_initialized()) {
459457
void *retaddr = __builtin_extract_return_addr(__builtin_return_address(0));
460-
void *sysimg_handle = jl_find_dynamic_library_by_addr(retaddr, /* throw_err */ 0);
461-
462-
if (sysimg_handle == NULL) {
458+
void *handle = jl_find_dynamic_library_by_addr(retaddr, 0);
459+
if (handle == NULL) {
463460
fprintf(stderr, "error: runtime auto-initialization failed due to bad sysimage lookup\n"
464461
" (this should not happen, please file a bug report)\n");
465-
abort();
462+
exit(1);
466463
}
467-
468-
assert(0 && "TODO: implement auto-init");
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);
467+
return &jl_get_current_task()->gcstack;
469468
}
470469

471470
return jl_adopt_thread();

0 commit comments

Comments
 (0)