Skip to content

Commit 01bb043

Browse files
committed
fixup! staticdata: remove reinit_ccallable
1 parent cf6b5ac commit 01bb043

File tree

9 files changed

+53
-214
lines changed

9 files changed

+53
-214
lines changed

src/aotcompile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvm
666666
else {
667667
jl_value_t *sig = jl_array_ptr_ref(codeinfos, ++i);
668668
assert(jl_is_type(item) && jl_is_type(sig));
669-
jl_compile_extern_c(wrap(&clone), &params, NULL, item, sig);
669+
jl_generate_ccallable(clone.getModuleUnlocked(), nullptr, item, sig, params);
670670
}
671671
}
672672
// finally, make sure all referenced methods get fixed up, particularly if the user declined to compile them

src/codegen-stubs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ JL_DLLEXPORT void jl_get_llvm_gvs_fallback(void *native_code, arraylist_t *gvs)
1717
JL_DLLEXPORT void jl_get_llvm_external_fns_fallback(void *native_code, arraylist_t *gvs) UNAVAILABLE
1818
JL_DLLEXPORT void jl_get_llvm_mis_fallback(void *native_code, arraylist_t* MIs) UNAVAILABLE
1919

20-
JL_DLLEXPORT void jl_extern_c_fallback(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name) UNAVAILABLE
2120
JL_DLLEXPORT jl_value_t *jl_dump_method_asm_fallback(jl_method_instance_t *linfo, size_t world,
2221
char emit_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
2322
JL_DLLEXPORT jl_value_t *jl_dump_function_ir_fallback(jl_llvmf_dump_t *dump, char strip_ir_metadata, char dump_module, const char *debuginfo) UNAVAILABLE

src/gf.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4605,6 +4605,44 @@ JL_DLLEXPORT void jl_typeinf_timing_end(uint64_t start, int is_recompile)
46054605
}
46064606
}
46074607

4608+
// declare a C-callable entry point; called during code loading from the toplevel
4609+
JL_DLLEXPORT void jl_extern_c(jl_value_t *declrt, jl_tupletype_t *sigt)
4610+
{
4611+
// validate arguments. try to do as many checks as possible here to avoid
4612+
// throwing errors later during codegen.
4613+
JL_TYPECHK(@ccallable, type, declrt);
4614+
if (!jl_is_tuple_type(sigt))
4615+
jl_type_error("@ccallable", (jl_value_t*)jl_anytuple_type_type, (jl_value_t*)sigt);
4616+
// check that f is a guaranteed singleton type
4617+
jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt);
4618+
if (!jl_is_datatype(ft) || !jl_is_datatype_singleton(ft))
4619+
jl_error("@ccallable: function object must be a singleton");
4620+
4621+
// compute / validate return type
4622+
if (!jl_is_concrete_type(declrt) || jl_is_kind(declrt))
4623+
jl_error("@ccallable: return type must be concrete and correspond to a C type");
4624+
if (!jl_type_mappable_to_c(declrt))
4625+
jl_error("@ccallable: return type doesn't correspond to a C type");
4626+
4627+
// validate method signature
4628+
size_t i, nargs = jl_nparams(sigt);
4629+
for (i = 1; i < nargs; i++) {
4630+
jl_value_t *ati = jl_tparam(sigt, i);
4631+
if (!jl_is_concrete_type(ati) || jl_is_kind(ati) || !jl_type_mappable_to_c(ati))
4632+
jl_error("@ccallable: argument types must be concrete");
4633+
}
4634+
4635+
// save a record of this so that the alias is generated when we write an object file
4636+
jl_method_t *meth = (jl_method_t*)jl_methtable_lookup(ft->name->mt, (jl_value_t*)sigt, jl_atomic_load_acquire(&jl_world_counter));
4637+
if (!jl_is_method(meth))
4638+
jl_error("@ccallable: could not find requested method");
4639+
JL_GC_PUSH1(&meth);
4640+
meth->ccallable = jl_svec2(declrt, (jl_value_t*)sigt);
4641+
jl_gc_wb(meth, meth->ccallable);
4642+
JL_GC_POP();
4643+
}
4644+
4645+
46084646
#ifdef __cplusplus
46094647
}
46104648
#endif

src/jitlayers.cpp

Lines changed: 0 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -770,140 +770,6 @@ void jl_emit_codeinst_to_jit_impl(
770770
}
771771

772772

773-
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
774-
775-
// compile a C-callable alias
776-
extern "C" JL_DLLEXPORT_CODEGEN
777-
int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
778-
{
779-
auto ct = jl_current_task;
780-
bool timed = (ct->reentrant_timing & 1) == 0;
781-
if (timed)
782-
ct->reentrant_timing |= 1;
783-
uint64_t compiler_start_time = 0;
784-
uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled);
785-
if (measure_compile_time_enabled)
786-
compiler_start_time = jl_hrtime();
787-
jl_codegen_params_t *pparams = (jl_codegen_params_t*)p;
788-
DataLayout DL = pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout();
789-
Triple TargetTriple = pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple();
790-
orc::ThreadSafeContext ctx;
791-
auto into = unwrap(llvmmod);
792-
orc::ThreadSafeModule backing;
793-
bool success = true;
794-
const char *name = "";
795-
if (into == NULL) {
796-
ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext();
797-
backing = jl_create_ts_module("cextern", ctx, DL, TargetTriple);
798-
into = &backing;
799-
}
800-
{ // params scope
801-
jl_codegen_params_t params(into->getContext(), DL, TargetTriple);
802-
if (pparams == NULL) {
803-
params.cache = p == NULL;
804-
params.imaging_mode = 0;
805-
params.tsctx.getContext()->setDiscardValueNames(true);
806-
pparams = &params;
807-
}
808-
Module &M = *into->getModuleUnlocked();
809-
assert(pparams->tsctx.getContext() == &M.getContext());
810-
name = jl_generate_ccallable(&M, sysimg, declrt, sigt, *pparams);
811-
if (!sysimg && !p) {
812-
{ // drop lock to keep analyzer happy (since it doesn't know we have the only reference to it)
813-
auto release = std::move(params.tsctx_lock);
814-
}
815-
{ // lock scope
816-
jl_unique_gcsafe_lock lock(extern_c_lock);
817-
if (jl_ExecutionEngine->getGlobalValueAddress(name))
818-
success = false;
819-
}
820-
params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock
821-
if (success && params.cache) {
822-
size_t newest_world = jl_atomic_load_acquire(&jl_world_counter);
823-
for (auto &it : params.workqueue) { // really just zero or one, and just the ABI not the rest of the metadata
824-
jl_code_instance_t *codeinst = it.first;
825-
JL_GC_PROMISE_ROOTED(codeinst);
826-
jl_code_instance_t *newest_ci = jl_type_infer(jl_get_ci_mi(codeinst), newest_world, SOURCE_MODE_ABI);
827-
if (newest_ci) {
828-
if (jl_egal(codeinst->rettype, newest_ci->rettype))
829-
it.first = codeinst;
830-
jl_compile_codeinst_now(newest_ci);
831-
}
832-
}
833-
jl_analyze_workqueue(nullptr, params, true);
834-
assert(params.workqueue.empty());
835-
finish_params(&M, params);
836-
}
837-
}
838-
pparams = nullptr;
839-
}
840-
if (!sysimg && success && llvmmod == NULL) {
841-
{ // lock scope
842-
jl_unique_gcsafe_lock lock(extern_c_lock);
843-
if (!jl_ExecutionEngine->getGlobalValueAddress(name)) {
844-
{
845-
auto Lock = backing.getContext().getLock();
846-
jl_ExecutionEngine->optimizeDLSyms(*backing.getModuleUnlocked()); // safepoint
847-
}
848-
jl_ExecutionEngine->addModule(std::move(backing));
849-
success = jl_ExecutionEngine->getGlobalValueAddress(name);
850-
assert(success);
851-
}
852-
}
853-
}
854-
if (timed) {
855-
if (measure_compile_time_enabled) {
856-
auto end = jl_hrtime();
857-
jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time);
858-
}
859-
ct->reentrant_timing &= ~1ull;
860-
}
861-
return success;
862-
}
863-
864-
// declare a C-callable entry point; called during code loading from the toplevel
865-
extern "C" JL_DLLEXPORT_CODEGEN
866-
void jl_extern_c_impl(jl_value_t *declrt, jl_tupletype_t *sigt)
867-
{
868-
// validate arguments. try to do as many checks as possible here to avoid
869-
// throwing errors later during codegen.
870-
JL_TYPECHK(@ccallable, type, declrt);
871-
if (!jl_is_tuple_type(sigt))
872-
jl_type_error("@ccallable", (jl_value_t*)jl_anytuple_type_type, (jl_value_t*)sigt);
873-
// check that f is a guaranteed singleton type
874-
jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt);
875-
if (!jl_is_datatype(ft) || !jl_is_datatype_singleton(ft))
876-
jl_error("@ccallable: function object must be a singleton");
877-
878-
// compute / validate return type
879-
if (!jl_is_concrete_type(declrt) || jl_is_kind(declrt))
880-
jl_error("@ccallable: return type must be concrete and correspond to a C type");
881-
if (!jl_type_mappable_to_c(declrt))
882-
jl_error("@ccallable: return type doesn't correspond to a C type");
883-
884-
// validate method signature
885-
size_t i, nargs = jl_nparams(sigt);
886-
for (i = 1; i < nargs; i++) {
887-
jl_value_t *ati = jl_tparam(sigt, i);
888-
if (!jl_is_concrete_type(ati) || jl_is_kind(ati) || !jl_type_mappable_to_c(ati))
889-
jl_error("@ccallable: argument types must be concrete");
890-
}
891-
892-
// save a record of this so that the alias is generated when we write an object file
893-
jl_method_t *meth = (jl_method_t*)jl_methtable_lookup(ft->name->mt, (jl_value_t*)sigt, jl_atomic_load_acquire(&jl_world_counter));
894-
if (!jl_is_method(meth))
895-
jl_error("@ccallable: could not find requested method");
896-
JL_GC_PUSH1(&meth);
897-
meth->ccallable = jl_svec2(declrt, (jl_value_t*)sigt);
898-
jl_gc_wb(meth, meth->ccallable);
899-
JL_GC_POP();
900-
901-
// create the alias in the current runtime environment
902-
int success = jl_compile_extern_c(NULL, NULL, NULL, declrt, (jl_value_t*)sigt);
903-
if (!success)
904-
jl_error("@ccallable was already defined for this method name");
905-
}
906-
907773
extern "C" JL_DLLEXPORT_CODEGEN
908774
int jl_compile_codeinst_impl(jl_code_instance_t *ci)
909775
{

src/jitlayers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ struct jl_codegen_params_t {
269269
~jl_codegen_params_t() JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE = default;
270270
};
271271

272+
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
273+
272274
jl_llvm_functions_t jl_emit_code(
273275
orc::ThreadSafeModule &M,
274276
jl_method_instance_t *mi,

src/jl_exported_funcs.inc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@
517517
YY(jl_dump_function_ir) \
518518
YY(jl_dump_method_asm) \
519519
YY(jl_emit_codeinst_to_jit) \
520-
YY(jl_extern_c) \
521520
YY(jl_get_llvmf_defn) \
522521
YY(jl_get_llvm_function) \
523522
YY(jl_get_llvm_module) \
@@ -534,7 +533,6 @@
534533
YY(jl_register_fptrs) \
535534
YY(jl_generate_fptr_for_unspecialized) \
536535
YY(jl_compile_codeinst) \
537-
YY(jl_compile_extern_c) \
538536
YY(jl_teardown_codegen) \
539537
YY(jl_jit_total_bytes) \
540538
YY(jl_create_native) \

src/julia_internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,6 @@ JL_DLLEXPORT uint32_t jl_crc32c(uint32_t crc, const char *buf, size_t len);
19581958

19591959
JL_DLLIMPORT void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec);
19601960
JL_DLLIMPORT int jl_compile_codeinst(jl_code_instance_t *unspec);
1961-
JL_DLLIMPORT int jl_compile_extern_c(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt);
19621961
JL_DLLIMPORT void jl_emit_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src);
19631962

19641963
typedef struct {

test/llvmcall.jl

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -143,40 +143,6 @@ function call_jl_errno()
143143
end
144144
call_jl_errno()
145145

146-
module ObjLoadTest
147-
using Base: llvmcall, @ccallable
148-
using Test
149-
didcall = false
150-
""" jl_the_callback()
151-
152-
Sets the global didcall when it did the call
153-
"""
154-
@ccallable Cvoid function jl_the_callback()
155-
global didcall
156-
didcall = true
157-
nothing
158-
end
159-
@test_throws(ErrorException("@ccallable was already defined for this method name"),
160-
@eval @ccallable String jl_the_callback(not_the_method::Int) = "other")
161-
# Make sure everything up until here gets compiled
162-
@test jl_the_callback() === nothing
163-
@test jl_the_callback(1) == "other"
164-
didcall = false
165-
function do_the_call()
166-
llvmcall(
167-
("""declare void @jl_the_callback()
168-
define void @entry() #0 {
169-
0:
170-
call void @jl_the_callback()
171-
ret void
172-
}
173-
attributes #0 = { alwaysinline }
174-
""", "entry"),Cvoid,Tuple{})
175-
end
176-
do_the_call()
177-
@test didcall
178-
end
179-
180146
# Test for proper parenting
181147
local foo
182148
function foo()
@@ -189,26 +155,6 @@ function foo()
189155
end
190156
code_llvm(devnull, foo, ())
191157

192-
module CcallableRetTypeTest
193-
using Base: llvmcall, @ccallable
194-
using Test
195-
@ccallable function jl_test_returns_float()::Float64
196-
return 42
197-
end
198-
function do_the_call()
199-
llvmcall(
200-
("""declare double @jl_test_returns_float()
201-
define double @entry() #0 {
202-
0:
203-
%1 = call double @jl_test_returns_float()
204-
ret double %1
205-
}
206-
attributes #0 = { alwaysinline }
207-
""", "entry"),Float64,Tuple{})
208-
end
209-
@test do_the_call() === 42.0
210-
end
211-
212158
# Issue #48093 - test that non-external globals are not deduplicated
213159
function kernel()
214160
Base.llvmcall(("""

test/precompile.jl

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3-
using Test, Distributed, Random, Logging
4-
using REPL # doc lookup function
3+
using Test, Distributed, Random, Logging, Libdl
4+
using REPL # testing the doc lookup function should be outside of the scope of this file, but is currently tested here
55

66
include("precompile_utils.jl")
77

@@ -387,36 +387,27 @@ precompile_test_harness(false) do dir
387387
@test Base.object_build_id(Foo.a_vec_int) == Base.module_build_id(Foo)
388388
end
389389

390-
@eval begin function ccallable_test()
391-
Base.llvmcall(
392-
("""declare i32 @f35014(i32)
393-
define i32 @entry() {
394-
0:
395-
%1 = call i32 @f35014(i32 3)
396-
ret i32 %1
397-
}""", "entry"
398-
), Cint, Tuple{})
399-
end
400-
@test ccallable_test() == 4
401-
end
402-
403390
cachedir = joinpath(dir, "compiled", "v$(VERSION.major).$(VERSION.minor)")
404391
cachedir2 = joinpath(dir2, "compiled", "v$(VERSION.major).$(VERSION.minor)")
405392
cachefile = joinpath(cachedir, "$Foo_module.ji")
393+
@test isfile(cachefile)
406394
do_pkgimg = Base.JLOptions().use_pkgimages == 1 && Base.JLOptions().permalloc_pkgimg == 1
407395
if do_pkgimg || Base.JLOptions().use_pkgimages == 0
408396
if do_pkgimg
409-
ocachefile = Base.ocachefile_from_cachefile(cachefile)
397+
ocachefile = Base.ocachefile_from_cachefile(cachefile)::String
398+
@test isfile(ocachefile)
399+
let foo_ptr = Libdl.dlopen(ocachefile::String, RTLD_NOLOAD)
400+
f35014_ptr = Libdl.dlsym(foo_ptr, :f35014)
401+
@test ccall(f35014_ptr, Int32, (Int32,), 3) == 4
402+
end
410403
else
411404
ocachefile = nothing
412405
end
413406
# use _require_from_serialized to ensure that the test fails if
414407
# the module doesn't reload from the image:
415-
@test_warn "@ccallable was already defined for this method name" begin
416-
@test_logs (:warn, "Replacing module `$Foo_module`") begin
417-
m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile, Foo_file)
418-
@test isa(m, Module)
419-
end
408+
@test_logs (:warn, "Replacing module `$Foo_module`") begin
409+
m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile, Foo_file)
410+
@test isa(m, Module)
420411
end
421412
end
422413

0 commit comments

Comments
 (0)