@@ -37,13 +37,20 @@ function callable_ret_type(sig, types)
37
37
end
38
38
39
39
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
47
54
end
48
55
49
56
mutable struct TapedTask{Tdynamic_scope,Tfargs,Tmc<: MistyClosure }
@@ -53,6 +60,13 @@ mutable struct TapedTask{Tdynamic_scope,Tfargs,Tmc<:MistyClosure}
53
60
const position:: Base.RefValue{Int32}
54
61
end
55
62
63
+ struct CacheKey
64
+ world_age:: UInt
65
+ key:: Any
66
+ end
67
+
68
+ const mc_cache = Dict {CacheKey,MistyClosure} ()
69
+
56
70
"""
57
71
TapedTask(dynamic_scope::Any, f, args...; kwargs...)
58
72
@@ -170,12 +184,27 @@ julia> consume(t)
170
184
[`Libtask.get_dynamic_scope`](@ref) to anything you like.
171
185
"""
172
186
function TapedTask (dynamic_scope:: Any , fargs... ; kwargs... )
173
- seed_id! ()
174
187
all_args = isempty (kwargs) ? fargs : (Core. kwcall, getfield (kwargs, :data ), fargs... )
188
+ seed_id! ()
175
189
mc, count_ref = build_callable (typeof (all_args))
176
190
return TapedTask (dynamic_scope, all_args, mc, count_ref)
177
191
end
178
192
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
+
179
208
"""
180
209
set_dynamic_scope!(t::TapedTask, new_dynamic_scope)::Nothing
181
210
@@ -335,7 +364,7 @@ const TypeInfo = Tuple{Vector{Any},Dict{ID,Type}}
335
364
Central definition of typeof, which is specific to the use-required in this package.
336
365
"""
337
366
_typeof (x) = Base. _stable_typeof (x)
338
- _typeof (x:: Tuple ) = Tuple{tuple_map (_typeof, x)... }
367
+ _typeof (x:: Tuple ) = Tuple{map (_typeof, x)... }
339
368
_typeof (x:: NamedTuple{names} ) where {names} = NamedTuple{names,_typeof (Tuple (x))}
340
369
341
370
"""
@@ -641,6 +670,8 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}
641
670
push! (inst_pairs, (id, inst))
642
671
elseif Meta. isexpr (stmt, :gc_preserve_end )
643
672
push! (inst_pairs, (id, inst))
673
+ elseif Meta. isexpr (stmt, :throw_undef_if_not )
674
+ push! (inst_pairs, (id, inst))
644
675
elseif stmt isa Nothing
645
676
push! (inst_pairs, (id, inst))
646
677
elseif stmt isa GlobalRef
0 commit comments