Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't permalloc the pkgimgs, but add option for PkgCacheInspector #49940

Merged
merged 1 commit into from May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions base/options.jl
Expand Up @@ -54,6 +54,7 @@ struct JLOptions
rr_detach::Int8
strip_metadata::Int8
strip_ir::Int8
permalloc_pkgimg::Int8
heap_size_hint::UInt64
end

Expand Down
12 changes: 12 additions & 0 deletions src/jloptions.c
Expand Up @@ -87,6 +87,7 @@ JL_DLLEXPORT void jl_init_options(void)
0, // rr-detach
0, // strip-metadata
0, // strip-ir
0, // permalloc_pkgimg
0, // heap-size-hint
};
jl_options_initialized = 1;
Expand Down Expand Up @@ -209,6 +210,7 @@ static const char opts_hidden[] =
" --trace-compile={stderr,name}\n"
" Print precompile statements for methods compiled during execution or save to a path\n"
" --image-codegen Force generate code in imaging mode\n"
" --permalloc-pkgimg={yes|no*} Copy the data section of package images into memory\n"
;

JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
Expand Down Expand Up @@ -254,6 +256,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
opt_strip_ir,
opt_heap_size_hint,
opt_gc_threads,
opt_permalloc_pkgimg
};
static const char* const shortopts = "+vhqH:e:E:L:J:C:it:p:O:g:";
static const struct option longopts[] = {
Expand Down Expand Up @@ -313,6 +316,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
{ "rr-detach", no_argument, 0, opt_rr_detach },
{ "strip-metadata", no_argument, 0, opt_strip_metadata },
{ "strip-ir", no_argument, 0, opt_strip_ir },
{ "permalloc-pkgimg",required_argument, 0, opt_permalloc_pkgimg },
{ "heap-size-hint", required_argument, 0, opt_heap_size_hint },
{ 0, 0, 0, 0 }
};
Expand Down Expand Up @@ -827,6 +831,14 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
jl_errorf("julia: --gcthreads=<n>; n must be an integer >= 1");
jl_options.ngcthreads = (int16_t)ngcthreads;
break;
case opt_permalloc_pkgimg:
if (!strcmp(optarg,"yes"))
jl_options.permalloc_pkgimg = 1;
else if (!strcmp(optarg,"no"))
jl_options.permalloc_pkgimg = 0;
else
jl_errorf("julia: invalid argument to --permalloc-pkgimg={yes|no} (%s)", optarg);
break;
default:
jl_errorf("julia: unhandled option -- %c\n"
"This is a bug, please report it.", c);
Expand Down
1 change: 1 addition & 0 deletions src/jloptions.h
Expand Up @@ -58,6 +58,7 @@ typedef struct {
int8_t rr_detach;
int8_t strip_metadata;
int8_t strip_ir;
int8_t permalloc_pkgimg;
uint64_t heap_size_hint;
} jl_options_t;

Expand Down
29 changes: 19 additions & 10 deletions src/staticdata.c
Expand Up @@ -71,6 +71,7 @@ External links:
*/
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h> // printf
#include <inttypes.h> // PRIxPTR

Expand Down Expand Up @@ -3364,7 +3365,7 @@ static jl_value_t *jl_validate_cache_file(ios_t *f, jl_array_t *depmods, uint64_
}

// TODO?: refactor to make it easier to create the "package inspector"
static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *image, jl_array_t *depmods, int completeinfo, const char *pkgname)
static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *image, jl_array_t *depmods, int completeinfo, const char *pkgname, bool needs_permalloc)
{
JL_TIMING(LOAD_IMAGE, LOAD_Pkgimg);
jl_timing_printf(JL_TIMING_DEFAULT_BLOCK, pkgname);
Expand All @@ -3377,7 +3378,7 @@ static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *im
return verify_fail;

assert(datastartpos > 0 && datastartpos < dataendpos);

needs_permalloc = jl_options.permalloc_pkgimg || needs_permalloc;
jl_value_t *restored = NULL;
jl_array_t *init_order = NULL, *extext_methods = NULL, *new_specializations = NULL, *method_roots_list = NULL, *ext_targets = NULL, *edges = NULL;
jl_svec_t *cachesizes_sv = NULL;
Expand All @@ -3389,14 +3390,22 @@ static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *im
ios_bufmode(f, bm_none);
JL_SIGATOMIC_BEGIN();
size_t len = dataendpos - datastartpos;
char *sysimg = (char*)jl_gc_perm_alloc(len, 0, 64, 0);
char *sysimg;
bool success = !needs_permalloc;
ios_seek(f, datastartpos);
if (ios_readall(f, sysimg, len) != len || jl_crc32c(0, sysimg, len) != (uint32_t)checksum) {
restored = jl_get_exceptionf(jl_errorexception_type, "Error reading system image file.");
if (needs_permalloc)
sysimg = (char*)jl_gc_perm_alloc(len, 0, 64, 0);
else
sysimg = &f->buf[f->bpos];
if (needs_permalloc)
success = ios_readall(f, sysimg, len) == len;
if (!success || jl_crc32c(0, sysimg, len) != (uint32_t)checksum) {
restored = jl_get_exceptionf(jl_errorexception_type, "Error reading package image file.");
JL_SIGATOMIC_END();
}
else {
ios_close(f);
if (needs_permalloc)
ios_close(f);
ios_static_buffer(f, sysimg, len);
pkgcachesizes cachesizes;
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);
Expand Down Expand Up @@ -3442,11 +3451,11 @@ static void jl_restore_system_image_from_stream(ios_t *f, jl_image_t *image, uin
jl_restore_system_image_from_stream_(f, image, NULL, checksum | ((uint64_t)0xfdfcfbfa << 32), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}

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, const char *pkgname)
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, const char *pkgname, bool needs_permalloc)
{
ios_t f;
ios_static_buffer(&f, (char*)buf, sz);
jl_value_t *ret = jl_restore_package_image_from_stream(&f, image, depmods, completeinfo, pkgname);
jl_value_t *ret = jl_restore_package_image_from_stream(&f, image, depmods, completeinfo, pkgname, needs_permalloc);
ios_close(&f);
return ret;
}
Expand All @@ -3459,7 +3468,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_incremental(const char *fname, jl_array_t *d
"Cache file \"%s\" not found.\n", fname);
}
jl_image_t pkgimage = {};
jl_value_t *ret = jl_restore_package_image_from_stream(&f, &pkgimage, depmods, completeinfo, pkgname);
jl_value_t *ret = jl_restore_package_image_from_stream(&f, &pkgimage, depmods, completeinfo, pkgname, true);
ios_close(&f);
return ret;
}
Expand Down Expand Up @@ -3530,7 +3539,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_package_image_from_file(const char *fname, j

jl_image_t pkgimage = jl_init_processor_pkgimg(pkgimg_handle);

jl_value_t* mod = jl_restore_incremental_from_buf(pkgimg_data, &pkgimage, *plen, depmods, completeinfo, pkgname);
jl_value_t* mod = jl_restore_incremental_from_buf(pkgimg_data, &pkgimage, *plen, depmods, completeinfo, pkgname, false);

return mod;
}
Expand Down
25 changes: 14 additions & 11 deletions test/precompile.jl
Expand Up @@ -339,17 +339,20 @@ precompile_test_harness(false) do dir
cachedir = joinpath(dir, "compiled", "v$(VERSION.major).$(VERSION.minor)")
cachedir2 = joinpath(dir2, "compiled", "v$(VERSION.major).$(VERSION.minor)")
cachefile = joinpath(cachedir, "$Foo_module.ji")
if Base.JLOptions().use_pkgimages == 1
ocachefile = Base.ocachefile_from_cachefile(cachefile)
else
ocachefile = nothing
end
# use _require_from_serialized to ensure that the test fails if
# the module doesn't reload from the image:
@test_warn "@ccallable was already defined for this method name" begin
@test_logs (:warn, "Replacing module `$Foo_module`") begin
m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile)
@test isa(m, Module)
do_pkgimg = Base.JLOptions().use_pkgimages == 1 && Base.JLOptions().permalloc_pkgimg == 1
if do_pkgimg || Base.JLOptions().use_pkgimages == 0
if do_pkgimg
ocachefile = Base.ocachefile_from_cachefile(cachefile)
else
ocachefile = nothing
end
# use _require_from_serialized to ensure that the test fails if
# the module doesn't reload from the image:
@test_warn "@ccallable was already defined for this method name" begin
@test_logs (:warn, "Replacing module `$Foo_module`") begin
m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile)
@test isa(m, Module)
end
end
end

Expand Down