Skip to content

Commit 5135c4a

Browse files
committed
Caching and tweaks
1 parent ec9edb7 commit 5135c4a

File tree

1 file changed

+40
-9
lines changed

1 file changed

+40
-9
lines changed

src/copyable_task.jl

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,20 @@ function callable_ret_type(sig, types)
3737
end
3838

3939
function build_callable(sig::Type{<:Tuple})
40-
ir = Base.code_ircode_by_type(sig)[1][1]
41-
bb, refs, types = derive_copyable_task_ir(BBCode(ir))
42-
unoptimised_ir = IRCode(bb)
43-
optimised_ir = Mooncake.optimise_ir!(unoptimised_ir)
44-
mc_ret_type = callable_ret_type(sig, types)
45-
mc = Mooncake.misty_closure(mc_ret_type, optimised_ir, refs...; do_compile=true)
46-
return mc, refs[end]
40+
key = CacheKey(Base.get_world_counter(), sig)
41+
if haskey(mc_cache, key)
42+
v = fresh_copy(mc_cache[key])
43+
return v
44+
else
45+
ir = Base.code_ircode_by_type(sig)[1][1]
46+
bb, refs, types = derive_copyable_task_ir(BBCode(ir))
47+
unoptimised_ir = IRCode(bb)
48+
optimised_ir = Mooncake.optimise_ir!(unoptimised_ir)
49+
mc_ret_type = callable_ret_type(sig, types)
50+
mc = Mooncake.misty_closure(mc_ret_type, optimised_ir, refs...; do_compile=true)
51+
mc_cache[key] = mc
52+
return mc, refs[end]
53+
end
4754
end
4855

4956
mutable struct TapedTask{Tdynamic_scope,Tfargs,Tmc<:MistyClosure}
@@ -53,6 +60,13 @@ mutable struct TapedTask{Tdynamic_scope,Tfargs,Tmc<:MistyClosure}
5360
const position::Base.RefValue{Int32}
5461
end
5562

63+
struct CacheKey
64+
world_age::UInt
65+
key::Any
66+
end
67+
68+
const mc_cache = Dict{CacheKey,MistyClosure}()
69+
5670
"""
5771
TapedTask(dynamic_scope::Any, f, args...; kwargs...)
5872
@@ -170,12 +184,27 @@ julia> consume(t)
170184
[`Libtask.get_dynamic_scope`](@ref) to anything you like.
171185
"""
172186
function TapedTask(dynamic_scope::Any, fargs...; kwargs...)
173-
seed_id!()
174187
all_args = isempty(kwargs) ? fargs : (Core.kwcall, getfield(kwargs, :data), fargs...)
188+
seed_id!()
175189
mc, count_ref = build_callable(typeof(all_args))
176190
return TapedTask(dynamic_scope, all_args, mc, count_ref)
177191
end
178192

193+
function fresh_copy(mc::T) where {T<:MistyClosure}
194+
new_captures = Mooncake.tuple_map(mc.oc.captures) do r
195+
if eltype(r) <: DynamicCallable
196+
return Base.RefValue(DynamicCallable())
197+
elseif eltype(r) <: LazyCallable
198+
return _typeof(r)(eltype(r)())
199+
else
200+
return _typeof(r)()
201+
end
202+
end
203+
new_position = new_captures[end]
204+
new_position[] = -1
205+
return Mooncake.replace_captures(mc, new_captures), new_position
206+
end
207+
179208
"""
180209
set_dynamic_scope!(t::TapedTask, new_dynamic_scope)::Nothing
181210
@@ -335,7 +364,7 @@ const TypeInfo = Tuple{Vector{Any},Dict{ID,Type}}
335364
Central definition of typeof, which is specific to the use-required in this package.
336365
"""
337366
_typeof(x) = Base._stable_typeof(x)
338-
_typeof(x::Tuple) = Tuple{tuple_map(_typeof, x)...}
367+
_typeof(x::Tuple) = Tuple{map(_typeof, x)...}
339368
_typeof(x::NamedTuple{names}) where {names} = NamedTuple{names,_typeof(Tuple(x))}
340369

341370
"""
@@ -641,6 +670,8 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}
641670
push!(inst_pairs, (id, inst))
642671
elseif Meta.isexpr(stmt, :gc_preserve_end)
643672
push!(inst_pairs, (id, inst))
673+
elseif Meta.isexpr(stmt, :throw_undef_if_not)
674+
push!(inst_pairs, (id, inst))
644675
elseif stmt isa Nothing
645676
push!(inst_pairs, (id, inst))
646677
elseif stmt isa GlobalRef

0 commit comments

Comments
 (0)