From f653043215a19e5b69e8fa1328206057071b4874 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 17 Feb 2023 15:18:36 -0500 Subject: [PATCH 1/6] enable using external code in pkgimages This was unintentionally disabled (and incomplete) in the original PR for pkgimages. Co-authored-by: Valentin Churavy --- base/linking.jl | 4 +-- src/aotcompile.cpp | 24 ++------------ src/codegen.cpp | 83 +++++++++++++++++++++++++++++++--------------- src/jitlayers.h | 2 +- src/staticdata.c | 5 +-- 5 files changed, 65 insertions(+), 53 deletions(-) diff --git a/base/linking.jl b/base/linking.jl index 18cf128b342de..b2eea94b3cf26 100644 --- a/base/linking.jl +++ b/base/linking.jl @@ -162,8 +162,8 @@ function link_image_cmd(path, out) `$(ld()) $V $SHARED -o $out $WHOLE_ARCHIVE $path $NO_WHOLE_ARCHIVE $LIBDIR $PRIVATE_LIBDIR $SHLIBDIR $LIBS` end -function link_image(path, out, internal_stderr::IO = stderr, internal_stdout::IO = stdout) - run(link_image_cmd(path, out), Base.DevNull(), stderr, stdout) +function link_image(path, out, internal_stderr::IO=stderr, internal_stdout::IO=stdout) + run(link_image_cmd(path, out), Base.DevNull(), internal_stderr, internal_stdout) end end # module Linking diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index d1694eaf9e0d5..907735dfa0128 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -369,34 +369,16 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm size_t offset = gvars.size(); data->jl_external_to_llvm.resize(params.external_fns.size()); - auto tbaa_const = tbaa_make_child_with_context(*ctxt.getContext(), "jtbaa_const", nullptr, true).first; for (auto &extern_fn : params.external_fns) { jl_code_instance_t *this_code = std::get<0>(extern_fn.first); bool specsig = std::get<1>(extern_fn.first); assert(specsig && "Error external_fns doesn't handle non-specsig yet"); - (void)specsig; - Function *F = extern_fn.second; - Module *M = F->getParent(); - - Type *T_funcp = F->getFunctionType()->getPointerTo(); - // Can't create a GC with type FunctionType. Alias also doesn't work - GlobalVariable *GV = new GlobalVariable(*M, T_funcp, false, - GlobalVariable::ExternalLinkage, - Constant::getNullValue(T_funcp), - F->getName()); - - - // Need to insert load instruction, thus we can't use replace all uses with - replaceUsesWithLoad(*F, [GV](Instruction &) { return GV; }, tbaa_const); - - assert(F->getNumUses() == 0); // declaration counts as use - GV->takeName(F); - F->eraseFromParent(); - + (void) specsig; + GlobalVariable *F = extern_fn.second; size_t idx = gvars.size() - offset; assert(idx >= 0); data->jl_external_to_llvm.at(idx) = this_code; - gvars.push_back(std::string(GV->getName())); + gvars.push_back(std::string(F->getName())); } // clones the contents of the module `m` to the shadow_output collector diff --git a/src/codegen.cpp b/src/codegen.cpp index c2a042967c97a..36b677532a1e4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1542,7 +1542,7 @@ class jl_codectx_t { jl_codegen_params_t &emission_context; llvm::MapVector call_targets; std::map &global_targets; - std::map, Function*> &external_calls; + std::map, GlobalVariable*> &external_calls; Function *f = NULL; // local var info. globals are not in here. std::vector slots; @@ -1704,7 +1704,7 @@ static Value *get_current_task(jl_codectx_t &ctx); static Value *get_current_ptls(jl_codectx_t &ctx); static Value *get_last_age_field(jl_codectx_t &ctx); static void CreateTrap(IRBuilder<> &irbuilder, bool create_new_block = true); -static CallInst *emit_jlcall(jl_codectx_t &ctx, Function *theFptr, Value *theF, +static CallInst *emit_jlcall(jl_codectx_t &ctx, FunctionCallee theFptr, Value *theF, const jl_cgval_t *args, size_t nargs, JuliaFunction *trampoline); static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction *theFptr, Value *theF, const jl_cgval_t *args, size_t nargs, JuliaFunction *trampoline); @@ -4039,14 +4039,14 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } // Returns ctx.types().T_prjlvalue -static CallInst *emit_jlcall(jl_codectx_t &ctx, Function *theFptr, Value *theF, +static CallInst *emit_jlcall(jl_codectx_t &ctx, FunctionCallee theFptr, Value *theF, const jl_cgval_t *argv, size_t nargs, JuliaFunction *trampoline) { ++EmittedJLCalls; Function *TheTrampoline = prepare_call(trampoline); // emit arguments SmallVector theArgs; - theArgs.push_back(theFptr); + theArgs.push_back(theFptr.getCallee()); if (theF) theArgs.push_back(theF); for (size_t i = 0; i < nargs; i++) { @@ -4067,7 +4067,7 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction *theFptr, Value *t } -static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_t *mi, jl_value_t *jlretty, StringRef specFunctionObject, +static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_t *mi, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, const jl_cgval_t *argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty) { ++EmittedSpecfunCalls; @@ -4143,7 +4143,22 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_ idx++; } assert(idx == nfargs); - CallInst *call = ctx.builder.CreateCall(returninfo.decl, ArrayRef(&argvals[0], nfargs)); + Value *callee = returninfo.decl; + if (fromexternal) { + std::string namep("p"); + namep += returninfo.decl->getName(); + GlobalVariable *GV = cast_or_null(jl_Module->getNamedValue(namep)); + if (GV == nullptr) { + GV = new GlobalVariable(*jl_Module, callee->getType(), false, + GlobalVariable::ExternalLinkage, + Constant::getNullValue(callee->getType()), + namep); + ctx.external_calls[std::make_tuple(fromexternal, true)] = GV; + } + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + callee = ai.decorateInst(ctx.builder.CreateAlignedLoad(callee->getType(), GV, Align(sizeof(void*)))); + } + CallInst *call = ctx.builder.CreateCall(cft, callee, ArrayRef(&argvals[0], nfargs)); call->setAttributes(returninfo.decl->getAttributes()); jl_cgval_t retval; @@ -4182,13 +4197,30 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_ return update_julia_type(ctx, retval, inferred_retty); } -static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty, StringRef specFunctionObject, +static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, const jl_cgval_t *argv, size_t nargs, jl_value_t *inferred_retty) { - auto theFptr = cast( - jl_Module->getOrInsertFunction(specFunctionObject, ctx.types().T_jlfunc).getCallee()); - addRetAttr(theFptr, Attribute::NonNull); - Value *ret = emit_jlcall(ctx, theFptr, nullptr, argv, nargs, julia_call); + Value *theFptr; + if (fromexternal) { + std::string namep("p"); + namep += specFunctionObject; + GlobalVariable *GV = cast_or_null(jl_Module->getNamedValue(namep)); + Type *pfunc = ctx.types().T_jlfunc->getPointerTo(); + if (GV == nullptr) { + GV = new GlobalVariable(*jl_Module, pfunc, false, + GlobalVariable::ExternalLinkage, + Constant::getNullValue(pfunc), + namep); + ctx.external_calls[std::make_tuple(fromexternal, false)] = GV; + } + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + theFptr = ai.decorateInst(ctx.builder.CreateAlignedLoad(pfunc, GV, Align(sizeof(void*)))); + } + else { + theFptr = jl_Module->getOrInsertFunction(specFunctionObject, ctx.types().T_jlfunc).getCallee(); + addRetAttr(cast(theFptr), Attribute::NonNull); + } + Value *ret = emit_jlcall(ctx, FunctionCallee(ctx.types().T_jlfunc, theFptr), nullptr, argv, nargs, julia_call); return update_julia_type(ctx, mark_julia_type(ctx, ret, true, jlretty), inferred_retty); } @@ -4223,12 +4255,12 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const FunctionType *ft = ctx.f->getFunctionType(); StringRef protoname = ctx.f->getName(); if (ft == ctx.types().T_jlfunc) { - result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, argv, nargs, rt); + result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, nullptr, argv, nargs, rt); handled = true; } else if (ft != ctx.types().T_jlfuncparams) { unsigned return_roots = 0; - result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, argv, nargs, &cc, &return_roots, rt); + result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt); handled = true; } } @@ -4251,7 +4283,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const bool cache_valid = ctx.use_cache; bool external = false; if (ctx.external_linkage) { - if (0 && jl_object_in_image((jl_value_t*)codeinst)) { + if (specsig && jl_object_in_image((jl_value_t*)codeinst)) { + // TODO: add !specsig support to aotcompile.cpp // Target is present in another pkgimage cache_valid = true; external = true; @@ -4277,25 +4310,19 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const auto it = ctx.call_targets.find(codeinst); if (need_to_emit && it != ctx.call_targets.end()) { protoname = std::get<2>(it->second)->getName(); - need_to_emit = false; + need_to_emit = external = false; } if (need_to_emit) { raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add(&globalUniqueGeneratedNames, 1); protoname = StringRef(name); + cache_valid = external = false; } jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; unsigned return_roots = 0; if (specsig) - result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, argv, nargs, &cc, &return_roots, rt); + result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt); else - result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, argv, nargs, rt); - if (external) { - assert(!need_to_emit); - auto calledF = jl_Module->getFunction(protoname); - assert(calledF); - // TODO: Check if already present? - ctx.external_calls[std::make_tuple(codeinst, specsig)] = calledF; - } + result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt); handled = true; if (need_to_emit) { Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); @@ -5619,8 +5646,9 @@ static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_cod auto invoke = jl_atomic_load_relaxed(&codeinst->invoke); bool cache_valid = params.cache; - if (params.external_linkage) { - if (0 && jl_object_in_image((jl_value_t*)codeinst)) { + // TODO: Add support for jlinvoke to aotcompile.cpp + if (0 && params.external_linkage) { + if (jl_object_in_image((jl_value_t*)codeinst)) { // Target is present in another pkgimage cache_valid = true; } @@ -8537,8 +8565,9 @@ void jl_compile_workqueue( bool preal_specsig = false; auto invoke = jl_atomic_load_acquire(&codeinst->invoke); bool cache_valid = params.cache; + // If we added it to the work-queue and we compile for external_linkage, the cache is not valid if (params.external_linkage) { - cache_valid = 0 && jl_object_in_image((jl_value_t*)codeinst); + cache_valid = 0; } // WARNING: isspecsig is protected by the codegen-lock. If that lock is removed, then the isspecsig load needs to be properly atomically sequenced with this. if (cache_valid && invoke != NULL) { diff --git a/src/jitlayers.h b/src/jitlayers.h index f62ee595a843b..db6f68bd3f3b6 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -190,7 +190,7 @@ typedef struct _jl_codegen_params_t { // outputs std::vector> workqueue; std::map globals; - std::map, Function*> external_fns; + std::map, GlobalVariable*> external_fns; std::map ditypes; std::map llvmtypes; DenseMap mergedConstants; diff --git a/src/staticdata.c b/src/staticdata.c index 9ae00b395a0e8..05579c9a53890 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1913,11 +1913,12 @@ static uint32_t write_gvars(jl_serializer_state *s, arraylist_t *globals, arrayl } for (size_t i = 0; i < external_fns->len; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)external_fns->items[i]; + assert(ci && ci->isspecsig); uintptr_t item = backref_id(s, (void*)ci, s->link_ids_external_fnvars); uintptr_t reloc = get_reloc_for_item(item, 0); write_reloc_t(s->gvar_record, reloc); } - return globals->len + 1; + return globals->len; } // Pointer relocation for native-code referenced global variables @@ -1962,7 +1963,7 @@ static void jl_root_new_gvars(jl_serializer_state *s, jl_image_t *image, uint32_ v = (uintptr_t)jl_as_global_root((jl_value_t*)v); } else { jl_code_instance_t *codeinst = (jl_code_instance_t*) v; - assert(codeinst && (codeinst->specsigflags & 0b01)); + assert(codeinst && (codeinst->specsigflags & 0b01) && codeinst->specptr.fptr); v = (uintptr_t)codeinst->specptr.fptr; } *gv = v; From b89cf36c58db2ea0854016f7c3701d5850403ddb Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 21 Feb 2023 19:59:50 -0500 Subject: [PATCH 2/6] Simplify logic in aotcompile.cpp --- src/codegen.cpp | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 36b677532a1e4..7fe5f22d226de 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4280,17 +4280,17 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const std::string name; StringRef protoname; bool need_to_emit = true; - bool cache_valid = ctx.use_cache; + bool cache_valid = ctx.use_cache || ctx.external_linkage; bool external = false; - if (ctx.external_linkage) { - if (specsig && jl_object_in_image((jl_value_t*)codeinst)) { - // TODO: add !specsig support to aotcompile.cpp - // Target is present in another pkgimage - cache_valid = true; - external = true; - } + + // Check if we already queued this up + auto it = ctx.call_targets.find(codeinst); + if (need_to_emit && it != ctx.call_targets.end()) { + protoname = std::get<2>(it->second)->getName(); + need_to_emit = cache_valid = false; } + // Check if it is already compiled (either JIT or externally) if (cache_valid) { // optimization: emit the correct name immediately, if we know it // TODO: use `emitted` map here too to try to consolidate names? @@ -4303,19 +4303,22 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const invoke = jl_atomic_load_relaxed(&codeinst->invoke); if (specsig ? jl_atomic_load_relaxed(&codeinst->specsigflags) & 0b1 : invoke == jl_fptr_args_addr) { protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst); - need_to_emit = false; + if (ctx.external_linkage) { + // TODO: Add !specsig support to aotcompile.cpp + if (specsig && protoname.starts_with("jlsys")) { + external = true; + need_to_emit = false; + } + } + else { // ctx.use_cache + need_to_emit = false; + } } } } - auto it = ctx.call_targets.find(codeinst); - if (need_to_emit && it != ctx.call_targets.end()) { - protoname = std::get<2>(it->second)->getName(); - need_to_emit = external = false; - } if (need_to_emit) { raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add(&globalUniqueGeneratedNames, 1); protoname = StringRef(name); - cache_valid = external = false; } jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; unsigned return_roots = 0; @@ -5644,15 +5647,7 @@ static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_cod Function *theFunc; Value *theFarg; auto invoke = jl_atomic_load_relaxed(&codeinst->invoke); - bool cache_valid = params.cache; - // TODO: Add support for jlinvoke to aotcompile.cpp - if (0 && params.external_linkage) { - if (jl_object_in_image((jl_value_t*)codeinst)) { - // Target is present in another pkgimage - cache_valid = true; - } - } if (cache_valid && invoke != NULL) { StringRef theFptrName = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)invoke, codeinst); @@ -8565,10 +8560,6 @@ void jl_compile_workqueue( bool preal_specsig = false; auto invoke = jl_atomic_load_acquire(&codeinst->invoke); bool cache_valid = params.cache; - // If we added it to the work-queue and we compile for external_linkage, the cache is not valid - if (params.external_linkage) { - cache_valid = 0; - } // WARNING: isspecsig is protected by the codegen-lock. If that lock is removed, then the isspecsig load needs to be properly atomically sequenced with this. if (cache_valid && invoke != NULL) { auto fptr = jl_atomic_load_relaxed(&codeinst->specptr.fptr); From 1fe9bac38526d0a9b6bc08a06a2e87fb833b8f9f Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 21 Feb 2023 20:03:00 -0500 Subject: [PATCH 3/6] fixup! Simplify logic in aotcompile.cpp --- src/codegen.cpp | 2 +- src/debuginfo.cpp | 2 +- src/jitlayers.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 7fe5f22d226de..44669eb52c9db 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4305,7 +4305,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst); if (ctx.external_linkage) { // TODO: Add !specsig support to aotcompile.cpp - if (specsig && protoname.starts_with("jlsys")) { + if (specsig && protoname.startswith("jsys")) { external = true; need_to_emit = false; } diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 2d087178afef1..5e95778ed97be 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -409,7 +409,7 @@ static std::pair jl_demangle(const char *name) JL_NOTSAFEPOINT strncmp(name, "japi3_", 6) && strncmp(name, "julia_", 6) && strncmp(name, "jsys1_", 6) && - strncmp(name, "jlsys_", 6)) + strncmp(name, "jsys0_", 6)) goto done; if (*start == '\0') goto done; diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index b489665f5629d..8ff8c70c97ec7 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1470,7 +1470,7 @@ StringRef JuliaOJIT::getFunctionAtAddress(uint64_t Addr, jl_code_instance_t *cod stream_fname << "jsys3_"; } else { - stream_fname << "jlsys_"; + stream_fname << "jsys0_"; } const char* unadorned_name = jl_symbol_name(codeinst->def->def.method->name); stream_fname << unadorned_name << "_" << RLST_inc++; From ae77ba2633324d3520f4e85461120152673f5c68 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 21 Feb 2023 22:59:36 -0500 Subject: [PATCH 4/6] go back to jl_object_in_image --- src/codegen.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 44669eb52c9db..52870c15a47cd 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4305,7 +4305,10 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst); if (ctx.external_linkage) { // TODO: Add !specsig support to aotcompile.cpp - if (specsig && protoname.startswith("jsys")) { + // FIXME: Need to guard against CI being allocated in image, + // but not filled in. If `fptr` non-null due to JIT compilation + // of this image, we will during loading find an empty CI. + if (specsig && jl_object_in_image((jl_value_t*)codeinst)) { external = true; need_to_emit = false; } From 15d936b0d17e524e02079e6d0a56a84dbce8b9d1 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 22 Feb 2023 00:43:57 -0500 Subject: [PATCH 5/6] use extra bir in specsigflags --- src/codegen.cpp | 6 ++---- src/julia.h | 4 +++- src/staticdata.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 52870c15a47cd..47b9519bbb2f0 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4305,10 +4305,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, codeinst); if (ctx.external_linkage) { // TODO: Add !specsig support to aotcompile.cpp - // FIXME: Need to guard against CI being allocated in image, - // but not filled in. If `fptr` non-null due to JIT compilation - // of this image, we will during loading find an empty CI. - if (specsig && jl_object_in_image((jl_value_t*)codeinst)) { + // Check that the codeinst is containing native code + if (specsig && jl_atomic_load_relaxed(&codeinst->specsigflags) & 0b100) { external = true; need_to_emit = false; } diff --git a/src/julia.h b/src/julia.h index 19dab5cd3a704..784f16485967c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -424,7 +424,9 @@ typedef struct _jl_code_instance_t { jl_value_t *argescapes; // escape information of call arguments // compilation state cache - _Atomic(uint8_t) specsigflags; // & 0b1 == specptr is a specialized function signature for specTypes->rettype, &0b10 == invokeptr matches specptr + _Atomic(uint8_t) specsigflags; // & 0b001 == specptr is a specialized function signature for specTypes->rettype + // & 0b010 == invokeptr matches specptr + // & 0b100 == From image _Atomic(uint8_t) precompile; // if set, this will be added to the output system image uint8_t relocatability; // nonzero if all roots are built into sysimg or tagged by module key _Atomic(jl_callptr_t) invoke; // jlcall entry point diff --git a/src/staticdata.c b/src/staticdata.c index 05579c9a53890..4b947f38f6356 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1077,7 +1077,7 @@ static void record_external_fns(jl_serializer_state *s, arraylist_t *external_fn #ifndef JL_NDEBUG for (size_t i = 0; i < external_fns->len; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)external_fns->items[i]; - assert(jl_object_in_image((jl_value_t*)ci)); + assert(jl_atomic_load_relaxed(&ci->specsigflags) & 0b100); } #endif } @@ -1889,7 +1889,7 @@ static void jl_update_all_fptrs(jl_serializer_state *s, jl_image_t *image) void *fptr = (void*)(base + offset); if (specfunc) { codeinst->specptr.fptr = fptr; - codeinst->specsigflags = 0b11; // TODO: set only if confirmed to be true + codeinst->specsigflags = 0b111; // TODO: set only if confirmed to be true } else { codeinst->invoke = (jl_callptr_t)fptr; @@ -1913,7 +1913,7 @@ static uint32_t write_gvars(jl_serializer_state *s, arraylist_t *globals, arrayl } for (size_t i = 0; i < external_fns->len; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)external_fns->items[i]; - assert(ci && ci->isspecsig); + assert(ci && (jl_atomic_load_relaxed(&ci->specsigflags) & 0b001)); uintptr_t item = backref_id(s, (void*)ci, s->link_ids_external_fnvars); uintptr_t reloc = get_reloc_for_item(item, 0); write_reloc_t(s->gvar_record, reloc); From a0887e3bb3d7fb5d58918ab0a15e33f5ab5ee177 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 23 Feb 2023 11:35:06 -0500 Subject: [PATCH 6/6] Apply suggestions from code review --- src/debuginfo.cpp | 2 +- src/jitlayers.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 5e95778ed97be..2d087178afef1 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -409,7 +409,7 @@ static std::pair jl_demangle(const char *name) JL_NOTSAFEPOINT strncmp(name, "japi3_", 6) && strncmp(name, "julia_", 6) && strncmp(name, "jsys1_", 6) && - strncmp(name, "jsys0_", 6)) + strncmp(name, "jlsys_", 6)) goto done; if (*start == '\0') goto done; diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 8ff8c70c97ec7..b489665f5629d 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1470,7 +1470,7 @@ StringRef JuliaOJIT::getFunctionAtAddress(uint64_t Addr, jl_code_instance_t *cod stream_fname << "jsys3_"; } else { - stream_fname << "jsys0_"; + stream_fname << "jlsys_"; } const char* unadorned_name = jl_symbol_name(codeinst->def->def.method->name); stream_fname << unadorned_name << "_" << RLST_inc++;