@@ -129,7 +129,8 @@ const deferred_codegen_jobs = Dict{Int, Any}()
129129
130130# We make this function explicitly callable so that we can drive OrcJIT's
131131# lazy compilation from, while also enabling recursive compilation.
132- Base. @ccallable Ptr{Cvoid} function deferred_codegen (ptr:: Ptr{Cvoid} )
132+ # see `register_deferred_codegen`
133+ function deferred_codegen (ptr:: Ptr{Cvoid} ):: Ptr{Cvoid}
133134 ptr
134135end
135136
149150 end
150151end
151152
153+ # Register deferred_codegen as a global function so that it can be called with `ccall("extern deferred_codegen"`
154+ # Called from __init__
155+ # On 1.11+ this is needed due to a Julia bug that drops the pointer when code-coverage is enabled.
156+ function register_deferred_codegen ()
157+ @dispose jljit= JuliaOJIT () begin
158+ jd = JITDylib (jljit)
159+
160+ address = LLVM. API. LLVMOrcJITTargetAddress (
161+ reinterpret (UInt, @cfunction (deferred_codegen, Ptr{Cvoid}, (Ptr{Cvoid},))))
162+ flags = LLVM. API. LLVMJITSymbolFlags (
163+ LLVM. API. LLVMJITSymbolGenericFlagsExported, 0 )
164+ name = mangle (jljit, " deferred_codegen" )
165+ symbol = LLVM. API. LLVMJITEvaluatedSymbol (address, flags)
166+ map = if LLVM. version () >= v " 15"
167+ LLVM. API. LLVMOrcCSymbolMapPair (name, symbol)
168+ else
169+ LLVM. API. LLVMJITCSymbolMapPair (name, symbol)
170+ end
171+
172+ mu = LLVM. absolute_symbols (Ref (map))
173+ LLVM. define (jd, mu)
174+ addr = lookup (jljit, " deferred_codegen" )
175+ @assert addr != C_NULL " Failed to register deferred_codegen"
176+ end
177+ return nothing
178+ end
179+
152180const __llvm_initialized = Ref (false )
153181
154182@locked function emit_llvm (@nospecialize (job:: CompilerJob ); kwargs... )
0 commit comments