Skip to content

Commit 4c6d306

Browse files
gbaraldiKristofferC
authored andcommitted
Don't permalloc the pkgimgs, but with an option (#49940)
(cherry picked from commit 229269b)
1 parent 3460774 commit 4c6d306

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

base/options.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct JLOptions
5353
rr_detach::Int8
5454
strip_metadata::Int8
5555
strip_ir::Int8
56+
permalloc_pkgimg::Int8
5657
heap_size_hint::UInt64
5758
end
5859

src/jloptions.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ JL_DLLEXPORT void jl_init_options(void)
8686
0, // rr-detach
8787
0, // strip-metadata
8888
0, // strip-ir
89+
0, // permalloc_pkgimg
8990
0, // heap-size-hint
9091
};
9192
jl_options_initialized = 1;
@@ -207,6 +208,7 @@ static const char opts_hidden[] =
207208
" --trace-compile={stderr,name}\n"
208209
" Print precompile statements for methods compiled during execution or save to a path\n"
209210
" --image-codegen Force generate code in imaging mode\n"
211+
" --permalloc-pkgimg={yes|no*} Copy the data section of package images into memory\n"
210212
;
211213

212214
JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
@@ -251,6 +253,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
251253
opt_strip_metadata,
252254
opt_strip_ir,
253255
opt_heap_size_hint,
256+
opt_permalloc_pkgimg
254257
};
255258
static const char* const shortopts = "+vhqH:e:E:L:J:C:it:p:O:g:";
256259
static const struct option longopts[] = {
@@ -309,6 +312,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
309312
{ "rr-detach", no_argument, 0, opt_rr_detach },
310313
{ "strip-metadata", no_argument, 0, opt_strip_metadata },
311314
{ "strip-ir", no_argument, 0, opt_strip_ir },
315+
{ "permalloc-pkgimg",required_argument, 0, opt_permalloc_pkgimg },
312316
{ "heap-size-hint", required_argument, 0, opt_heap_size_hint },
313317
{ 0, 0, 0, 0 }
314318
};
@@ -815,6 +819,14 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
815819
jl_errorf("julia: invalid argument to --heap-size-hint without memory size specified");
816820

817821
break;
822+
case opt_permalloc_pkgimg:
823+
if (!strcmp(optarg,"yes"))
824+
jl_options.permalloc_pkgimg = 1;
825+
else if (!strcmp(optarg,"no"))
826+
jl_options.permalloc_pkgimg = 0;
827+
else
828+
jl_errorf("julia: invalid argument to --permalloc-pkgimg={yes|no} (%s)", optarg);
829+
break;
818830
default:
819831
jl_errorf("julia: unhandled option -- %c\n"
820832
"This is a bug, please report it.", c);

src/jloptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ typedef struct {
5757
int8_t rr_detach;
5858
int8_t strip_metadata;
5959
int8_t strip_ir;
60+
int8_t permalloc_pkgimg;
6061
uint64_t heap_size_hint;
6162
} jl_options_t;
6263

src/staticdata.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ External links:
7171
*/
7272
#include <stdlib.h>
7373
#include <string.h>
74+
#include <stdbool.h>
7475
#include <stdio.h> // printf
7576
#include <inttypes.h> // PRIxPTR
7677

@@ -3297,7 +3298,7 @@ static jl_value_t *jl_validate_cache_file(ios_t *f, jl_array_t *depmods, uint64_
32973298
}
32983299

32993300
// TODO?: refactor to make it easier to create the "package inspector"
3300-
static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *image, jl_array_t *depmods, int completeinfo)
3301+
static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *image, jl_array_t *depmods, int completeinfo, bool needs_permalloc)
33013302
{
33023303
uint64_t checksum = 0;
33033304
int64_t dataendpos = 0;
@@ -3308,7 +3309,7 @@ static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *im
33083309
return verify_fail;
33093310

33103311
assert(datastartpos > 0 && datastartpos < dataendpos);
3311-
3312+
needs_permalloc = jl_options.permalloc_pkgimg || needs_permalloc;
33123313
jl_value_t *restored = NULL;
33133314
jl_array_t *init_order = NULL, *extext_methods = NULL, *new_specializations = NULL, *method_roots_list = NULL, *ext_targets = NULL, *edges = NULL;
33143315
jl_svec_t *cachesizes_sv = NULL;
@@ -3320,14 +3321,22 @@ static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *im
33203321
ios_bufmode(f, bm_none);
33213322
JL_SIGATOMIC_BEGIN();
33223323
size_t len = dataendpos - datastartpos;
3323-
char *sysimg = (char*)jl_gc_perm_alloc(len, 0, 64, 0);
3324+
char *sysimg;
3325+
bool success = !needs_permalloc;
33243326
ios_seek(f, datastartpos);
3325-
if (ios_readall(f, sysimg, len) != len || jl_crc32c(0, sysimg, len) != (uint32_t)checksum) {
3326-
restored = jl_get_exceptionf(jl_errorexception_type, "Error reading system image file.");
3327+
if (needs_permalloc)
3328+
sysimg = (char*)jl_gc_perm_alloc(len, 0, 64, 0);
3329+
else
3330+
sysimg = &f->buf[f->bpos];
3331+
if (needs_permalloc)
3332+
success = ios_readall(f, sysimg, len) == len;
3333+
if (!success || jl_crc32c(0, sysimg, len) != (uint32_t)checksum) {
3334+
restored = jl_get_exceptionf(jl_errorexception_type, "Error reading package image file.");
33273335
JL_SIGATOMIC_END();
33283336
}
33293337
else {
3330-
ios_close(f);
3338+
if (needs_permalloc)
3339+
ios_close(f);
33313340
ios_static_buffer(f, sysimg, len);
33323341
pkgcachesizes cachesizes;
33333342
jl_restore_system_image_from_stream_(f, image, depmods, checksum, (jl_array_t**)&restored, &init_order, &extext_methods, &new_specializations, &method_roots_list, &ext_targets, &edges, &base, &ccallable_list, &cachesizes);
@@ -3372,11 +3381,11 @@ static void jl_restore_system_image_from_stream(ios_t *f, jl_image_t *image, uin
33723381
jl_restore_system_image_from_stream_(f, image, NULL, checksum | ((uint64_t)0xfdfcfbfa << 32), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
33733382
}
33743383

3375-
JL_DLLEXPORT jl_value_t *jl_restore_incremental_from_buf(const char *buf, jl_image_t *image, size_t sz, jl_array_t *depmods, int completeinfo)
3384+
JL_DLLEXPORT jl_value_t *jl_restore_incremental_from_buf(const char *buf, jl_image_t *image, size_t sz, jl_array_t *depmods, int completeinfo, bool needs_permalloc)
33763385
{
33773386
ios_t f;
33783387
ios_static_buffer(&f, (char*)buf, sz);
3379-
jl_value_t *ret = jl_restore_package_image_from_stream(&f, image, depmods, completeinfo);
3388+
jl_value_t *ret = jl_restore_package_image_from_stream(&f, image, depmods, completeinfo, needs_permalloc);
33803389
ios_close(&f);
33813390
return ret;
33823391
}
@@ -3389,7 +3398,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_incremental(const char *fname, jl_array_t *d
33893398
"Cache file \"%s\" not found.\n", fname);
33903399
}
33913400
jl_image_t pkgimage = {};
3392-
jl_value_t *ret = jl_restore_package_image_from_stream(&f, &pkgimage, depmods, completeinfo);
3401+
jl_value_t *ret = jl_restore_package_image_from_stream(&f, &pkgimage, depmods, completeinfo, true);
33933402
ios_close(&f);
33943403
return ret;
33953404
}
@@ -3491,7 +3500,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_package_image_from_file(const char *fname, j
34913500
}
34923501
#endif
34933502

3494-
jl_value_t* mod = jl_restore_incremental_from_buf(pkgimg_data, &pkgimage, *plen, depmods, completeinfo);
3503+
jl_value_t* mod = jl_restore_incremental_from_buf(pkgimg_data, &pkgimage, *plen, depmods, completeinfo, false);
34953504

34963505
return mod;
34973506
}

test/precompile.jl

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -328,17 +328,20 @@ precompile_test_harness(false) do dir
328328
cachedir = joinpath(dir, "compiled", "v$(VERSION.major).$(VERSION.minor)")
329329
cachedir2 = joinpath(dir2, "compiled", "v$(VERSION.major).$(VERSION.minor)")
330330
cachefile = joinpath(cachedir, "$Foo_module.ji")
331-
if Base.JLOptions().use_pkgimages == 1
332-
ocachefile = Base.ocachefile_from_cachefile(cachefile)
333-
else
334-
ocachefile = nothing
335-
end
336-
# use _require_from_serialized to ensure that the test fails if
337-
# the module doesn't reload from the image:
338-
@test_warn "@ccallable was already defined for this method name" begin
339-
@test_logs (:warn, "Replacing module `$Foo_module`") begin
340-
m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile)
341-
@test isa(m, Module)
331+
do_pkgimg = Base.JLOptions().use_pkgimages == 1 && Base.JLOptions().permalloc_pkgimg == 1
332+
if do_pkgimg || Base.JLOptions().use_pkgimages == 0
333+
if do_pkgimg
334+
ocachefile = Base.ocachefile_from_cachefile(cachefile)
335+
else
336+
ocachefile = nothing
337+
end
338+
# use _require_from_serialized to ensure that the test fails if
339+
# the module doesn't reload from the image:
340+
@test_warn "@ccallable was already defined for this method name" begin
341+
@test_logs (:warn, "Replacing module `$Foo_module`") begin
342+
m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile)
343+
@test isa(m, Module)
344+
end
342345
end
343346
end
344347

0 commit comments

Comments
 (0)