Skip to content

Commit

Permalink
opaque_closure: Lookup optimized oc source inside code instance (#53878)
Browse files Browse the repository at this point in the history
This is an alternative to #53852. I don't think it's semantically legal
to put optimized source into the :source field of a method, but it
should be fine to just look it up from the CodeInstance. That said, this
is a bit of an unusual configuration. In particular it wasn't even
reachable with the surface APIs, which assumed that inferred IR was
always supposed to be compiled.
  • Loading branch information
Keno authored Mar 27, 2024
1 parent f4866b7 commit 4ee1022
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 7 deletions.
12 changes: 6 additions & 6 deletions base/opaque_closure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ end
function Core.OpaqueClosure(ir::IRCode, @nospecialize env...;
isva::Bool = false,
slotnames::Union{Nothing,Vector{Symbol}}=nothing,
do_compile::Bool = true)
kwargs...)
# NOTE: we need ir.argtypes[1] == typeof(env)
ir = Core.Compiler.copy(ir)
# if the user didn't specify a definition MethodInstance or filename Symbol to use for the debuginfo, set a filename now
Expand All @@ -78,20 +78,20 @@ function Core.OpaqueClosure(ir::IRCode, @nospecialize env...;
src.slotflags = fill(zero(UInt8), nargtypes)
src.slottypes = copy(ir.argtypes)
src = Core.Compiler.ir_to_codeinf!(src, ir)
return generate_opaque_closure(sig, Union{}, rt, src, nargs, isva, env...; do_compile)
return generate_opaque_closure(sig, Union{}, rt, src, nargs, isva, env...; kwargs...)
end

function Core.OpaqueClosure(src::CodeInfo, @nospecialize env...; rettype, sig, nargs, isva=false)
return generate_opaque_closure(sig, Union{}, rettype, src, nargs, isva, env...)
function Core.OpaqueClosure(src::CodeInfo, @nospecialize env...; rettype, sig, nargs, isva=false, kwargs...)
return generate_opaque_closure(sig, Union{}, rettype, src, nargs, isva, env...; kwargs...)
end

function generate_opaque_closure(@nospecialize(sig), @nospecialize(rt_lb), @nospecialize(rt_ub),
src::CodeInfo, nargs::Int, isva::Bool, @nospecialize env...;
mod::Module=@__MODULE__,
lineno::Int=0,
file::Union{Nothing,Symbol}=nothing,
isinferred::Bool=true,
do_compile::Bool=true)
do_compile::Bool=true,
isinferred::Bool=true)
return ccall(:jl_new_opaque_closure_from_code_info, Any, (Any, Any, Any, Any, Any, Cint, Any, Cint, Cint, Any, Cint, Cint),
sig, rt_lb, rt_ub, mod, src, lineno, file, nargs, isva, env, do_compile, isinferred)
end
14 changes: 13 additions & 1 deletion src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,19 @@ JL_DLLEXPORT const jl_callptr_t jl_fptr_interpret_call_addr = &jl_fptr_interpret
jl_value_t *jl_interpret_opaque_closure(jl_opaque_closure_t *oc, jl_value_t **args, size_t nargs)
{
jl_method_t *source = oc->source;
jl_code_info_t *code = jl_uncompress_ir(source, NULL, (jl_value_t*)source->source);
jl_code_info_t *code = NULL;
if (source->source) {
code = jl_uncompress_ir(source, NULL, (jl_value_t*)source->source);
}
else {
// OC constructed from optimized IR. It'll have a single specialization with optimized code
// in it that we'll try to interpret.
jl_svec_t *specializations = (jl_svec_t*)jl_atomic_load_relaxed(&source->specializations);
assert(jl_is_method_instance(specializations));
jl_method_instance_t *mi = (jl_method_instance_t *)specializations;
jl_code_instance_t *ci = jl_atomic_load_relaxed(&mi->cache);
code = jl_uncompress_ir(source, ci, jl_atomic_load_relaxed(&ci->inferred));
}
interpreter_state *s;
unsigned nroots = jl_source_nslots(code) + jl_source_nssavalues(code) + 2;
jl_task_t *ct = jl_current_task;
Expand Down
5 changes: 5 additions & 0 deletions test/opaque_closure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,8 @@ let ir = first(only(Base.code_ircode(sin, (Int,))))
oc = Core.OpaqueClosure(ir)
@test (Base.show_method(IOBuffer(), oc.source::Method); true)
end

let ir = first(only(Base.code_ircode(sin, (Int,))))
oc = Core.OpaqueClosure(ir; do_compile=false)
@test oc(1) == sin(1)
end

0 comments on commit 4ee1022

Please sign in to comment.