Skip to content

Commit c96907b

Browse files
committed
also cache calls that end up getting compiled in local method table
1 parent 96e0194 commit c96907b

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

src/construct.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ function prepare_call(@nospecialize(f), allargs; enter_generated = false)
248248
# The generator threw an error. Let's generate the same error by calling it.
249249
f(allargs[2:end]...)
250250
end
251-
isa(ret, Compiled) && return ret
251+
isa(ret, Compiled) && return ret, argtypes
252252
# Typical return
253253
framecode, lenv = ret
254254
if is_generated(method) && enter_generated
@@ -543,7 +543,7 @@ See [`enter_call`](@ref) for a similar approach not based on expressions.
543543
function enter_call_expr(expr; enter_generated = false)
544544
clear_caches()
545545
r = determine_method_for_expr(expr; enter_generated = enter_generated)
546-
if isa(r, Tuple)
546+
if r !== nothing && !isa(r[1], Compiled)
547547
return prepare_frame(r[1:end-1]...)
548548
end
549549
nothing
@@ -597,7 +597,7 @@ function enter_call(@nospecialize(finfo), @nospecialize(args...); kwargs...)
597597
error(f, " is a builtin or intrinsic")
598598
end
599599
r = prepare_call(f, allargs; enter_generated=enter_generated)
600-
if isa(r, Tuple)
600+
if r !== nothing && !isa(r[1], Compiled)
601601
return prepare_frame(r[1:end-1]...)
602602
end
603603
return nothing

src/localmethtable.jl

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int
2020
sig = d_meth.sig.parameters::SimpleVector
2121
if length(sig) == nargs
2222
# If this is generated, match only if `enter_generated` also matches
23-
fi = d_meth.frameinstance::FrameInstance
24-
matches = !is_generated(scopeof(fi.framecode)) || enter_generated == fi.enter_generated
23+
fi = d_meth.frameinstance
24+
if fi isa FrameInstance
25+
matches = !is_generated(scopeof(fi.framecode)) || enter_generated == fi.enter_generated
26+
else
27+
matches = !enter_generated
28+
end
2529
if matches
2630
for i = 1:nargs
2731
if !isa(fargs[i], sig[i])
@@ -38,7 +42,11 @@ function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int
3842
d_methprev.next = d_meth.next
3943
d_meth.next = d_meth1
4044
end
41-
return fi.framecode, fi.sparam_vals
45+
if fi isa Compiled
46+
return Compiled(), nothing
47+
else
48+
return fi.framecode, fi.sparam_vals
49+
end
4250
end
4351
end
4452
depth += 1
@@ -52,11 +60,16 @@ function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int
5260
fargs[1] = f = to_function(fargs[1])
5361
ret = prepare_call(f, fargs; enter_generated=enter_generated)
5462
ret === nothing && return f(fargs[2:end]...), nothing
55-
isa(ret, Compiled) && return ret, nothing
56-
framecode, args, env, argtypes = ret
57-
# Store the results of the method lookup in the local method table
58-
fi = FrameInstance(framecode, env, is_generated(scopeof(framecode)) && enter_generated)
59-
d_meth = DispatchableMethod(nothing, fi, argtypes)
63+
is_compiled = isa(ret[1], Compiled)
64+
local framecode
65+
if is_compiled
66+
d_meth = DispatchableMethod(nothing, Compiled(), ret[2])
67+
else
68+
framecode, args, env, argtypes = ret
69+
# Store the results of the method lookup in the local method table
70+
fi = FrameInstance(framecode, env, is_generated(scopeof(framecode)) && enter_generated)
71+
d_meth = DispatchableMethod(nothing, fi, argtypes)
72+
end
6073
if isassigned(parentframe.methodtables, idx)
6174
d_meth.next = parentframe.methodtables[idx]
6275
# Drop the oldest d_meth, if necessary
@@ -74,5 +87,9 @@ function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int
7487
d_meth.next = nothing
7588
end
7689
parentframe.methodtables[idx] = d_meth
77-
return framecode, env
90+
if is_compiled
91+
return Compiled(), nothing
92+
else
93+
return framecode, env
94+
end
7895
end

src/types.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ function breakpointchar(bps::BreakpointState)
5353
return bps.condition === falsecondition ? ' ' : 'd' # no breakpoint : disabled
5454
end
5555

56+
abstract type AbstractFrameInstance end
5657
mutable struct DispatchableMethod
5758
next::Union{Nothing,DispatchableMethod} # linked-list representation
58-
frameinstance::Any # really a FrameInstance but we have a cyclic dependency
59+
frameinstance::Union{Compiled, AbstractFrameInstance} # really a Union{Compiled, FrameInstance} but we have a cyclic dependency
5960
sig::Type # for speed of matching, this is a *concrete* signature. `sig <: frameinstance.framecode.scope.sig`
6061
end
6162

@@ -124,7 +125,7 @@ Fields:
124125
- `framecode`: the [`FrameCode`](@ref) for the method.
125126
- `sparam_vals`: the static parameter values for the method.
126127
"""
127-
struct FrameInstance
128+
struct FrameInstance <: AbstractFrameInstance
128129
framecode::FrameCode
129130
sparam_vals::SimpleVector
130131
enter_generated::Bool

0 commit comments

Comments
 (0)