Skip to content

Commit ee47df7

Browse files
authored
Micro-optimizations that reduce dynamic dispatch (#243)
1 parent ceee9c0 commit ee47df7

File tree

4 files changed

+17
-14
lines changed

4 files changed

+17
-14
lines changed

src/construct.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ function prepare_call(@nospecialize(f), allargs; enter_generated = false)
209209
elseif any(is_vararg_type, allargs)
210210
return nothing # https://github.com/JuliaLang/julia/issues/30995
211211
end
212-
argtypes = Tuple{map(_Typeof,allargs)...}
212+
argtypesv = Any[_Typeof(a) for a in allargs]
213+
argtypes = Tuple{argtypesv...}
213214
method = whichtt(argtypes)
214215
if method === nothing
215216
# Call it to generate the exact error
@@ -234,9 +235,10 @@ end
234235
function prepare_framedata(framecode, argvals::Vector{Any}, caller_will_catch_err::Bool=false)
235236
if isa(framecode.scope, Method)
236237
meth, src = framecode.scope::Method, framecode.src
238+
slotnames = src.slotnames::Vector{Any} # this is more strongly typed in julia.h than in jltypes.c
237239
ssavt = src.ssavaluetypes
238240
ng = isa(ssavt, Int) ? ssavt : length(ssavt::Vector{Any})
239-
nargs = length(argvals)
241+
nargs, meth_nargs = length(argvals), Int(meth.nargs)
240242
if !isempty(junk)
241243
olddata = first(junk)
242244
delete!(junk, olddata)
@@ -260,21 +262,21 @@ function prepare_framedata(framecode, argvals::Vector{Any}, caller_will_catch_er
260262
callargs = Any[]
261263
last_exception = Ref{Any}(nothing)
262264
end
263-
for i = 1:meth.nargs
264-
last_reference[framecode.src.slotnames[i]] = i
265-
if meth.isva && i == meth.nargs
265+
for i = 1:meth_nargs
266+
last_reference[slotnames[i]::Symbol] = i
267+
if meth.isva && i == meth_nargs
266268
locals[i] = nargs < i ? Some{Any}(()) : (let i=i; Some{Any}(ntuple(k->argvals[i+k-1], nargs-i+1)); end)
267269
break
268270
end
269271
locals[i] = nargs >= i ? Some{Any}(argvals[i]) : Some{Any}(())
270272
end
271273
# add local variables initially undefined
272-
for i = (meth.nargs+1):length(src.slotnames)
274+
for i = (meth_nargs+1):length(slotnames)
273275
locals[i] = nothing
274276
end
275277
else
276278
src = framecode.src
277-
locals = Vector{Union{Nothing,Some{Any}}}(undef, length(src.slotflags))
279+
locals = Vector{Union{Nothing,Some{Any}}}(undef, length(src.slotflags)) # src.slotflags is concretely typed, unlike slotnames
278280
fill!(locals, nothing)
279281
ssavalues = Vector{Any}(undef, length(src.code))
280282
sparams = Any[]

src/interpret.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ function do_assignment!(frame, @nospecialize(lhs), @nospecialize(rhs))
327327
data.ssavalues[lhs.id] = rhs
328328
elseif isa(lhs, SlotNumber)
329329
data.locals[lhs.id] = Some{Any}(rhs)
330-
data.last_reference[code.src.slotnames[lhs.id]] =
331-
lhs.id
330+
slotnames = code.src.slotnames::Vector{Any}
331+
data.last_reference[slotnames[lhs.id]::Symbol] = lhs.id
332332
elseif isa(lhs, GlobalRef)
333333
Core.eval(lhs.mod, :($(lhs.name) = $(QuoteNode(rhs))))
334334
elseif isa(lhs, Symbol)
@@ -430,7 +430,7 @@ function step_expr!(@nospecialize(recurse), frame, @nospecialize(node), istoplev
430430
throw(TypeError(nameof(frame), "if", Bool, node.args[1]))
431431
end
432432
if !arg
433-
return (frame.pc = node.args[2])
433+
return (frame.pc = node.args[2]::Int)
434434
end
435435
elseif node.head == :enter
436436
rhs = node.args[1]

src/localmethtable.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ Return the framecode and environment for a call specified by `fargs = [f, args..
77
`parentframecode` is the caller, and `idx` is the program-counter index.
88
If possible, `framecode` will be looked up from the local method tables of `parentframe`.
99
"""
10-
function get_call_framecode(fargs, parentframe::FrameCode, idx::Int; enter_generated::Bool=false)
10+
function get_call_framecode(fargs::Vector{Any}, parentframe::FrameCode, idx::Int; enter_generated::Bool=false)
1111
nargs = length(fargs) # includes f as the first "argument"
1212
# Determine whether we can look up the appropriate framecode in the local method table
1313
if isassigned(parentframe.methodtables, idx) # if this is the first call, this may not yet be set
14-
tme = tme1 = parentframe.methodtables[idx]
14+
tme = tme1 = parentframe.methodtables[idx]::TypeMapEntry
1515
local tmeprev
1616
depth = 1
1717
while true

src/utils.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,8 @@ function locals(frame::Frame)
293293
vars = Variable[]
294294
data, code = frame.framedata, frame.framecode
295295
added = Set{Symbol}()
296-
for sym in code.src.slotnames
296+
slotnames = code.src.slotnames::Vector{Any}
297+
for sym in slotnames
297298
sym added && continue
298299
idx = get(data.last_reference, sym, 0)
299300
idx == 0 && continue
@@ -381,4 +382,4 @@ function Base.display_error(io::IO, er, frame::Frame)
381382
printstyled(io, "ERROR: "; bold=true, color=Base.error_color())
382383
showerror(IOContext(io, :limit => true), er, frame)
383384
println(io)
384-
end
385+
end

0 commit comments

Comments
 (0)