Skip to content

Commit

Permalink
Reduce invalidations due to untyped fields of CodeInfo (#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy authored May 18, 2020
1 parent 57ad1e7 commit ff524e2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
8 changes: 4 additions & 4 deletions src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ end

function compute_ssa_mapping_delete_statements!(code::CodeInfo, stmts::Vector{Int})
stmts = unique!(sort!(stmts))
ssalookup = collect(1:length(code.codelocs))
ssalookup = collect(1:length(codelocs(code)))
cnt = 1
for i in 1:length(stmts)
start = stmts[i] + 1
stop = i == length(stmts) ? length(code.codelocs) : stmts[i+1]
stop = i == length(stmts) ? length(codelocs(code)) : stmts[i+1]
ssalookup[start:stop] .-= cnt
cnt += 1
end
Expand Down Expand Up @@ -183,15 +183,15 @@ function optimize!(code::CodeInfo, scope)
if !isempty(delete_idxs)
ssalookup = compute_ssa_mapping_delete_statements!(code, delete_idxs)
foreigncalls_idx = map(x -> ssalookup[x], foreigncalls_idx)
deleteat!(code.codelocs, delete_idxs)
deleteat!(codelocs(code), delete_idxs)
deleteat!(code.code, delete_idxs)
code.ssavaluetypes = length(code.code)
renumber_ssa!(code.code, ssalookup)
end

## Un-nest :call expressions (so that there will be only one :call per line)
# This will allow us to re-use args-buffers rather than having to allocate new ones each time.
old_code, old_codelocs = code.code, code.codelocs
old_code, old_codelocs = code.code, codelocs(code)
code.code = new_code = eltype(old_code)[]
code.codelocs = new_codelocs = Int32[]
ssainc = fill(1, length(old_code))
Expand Down
45 changes: 31 additions & 14 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,23 @@ end

## Location info

# These getters improve inference since fieldtype(CodeInfo, :linetable)
# and fieldtype(CodeInfo, :codelocs) are both Any
function linetable(arg)::Vector{Any}
if isa(arg, FrameCode)
arg = arg.src
end
return arg.linetable
end

function codelocs(arg)::Vector{Int32}
if isa(arg, FrameCode)
arg = arg.src
end
return arg.codelocs
end


function lineoffset(framecode::FrameCode)
offset = 0
scope = framecode.scope
Expand All @@ -224,7 +241,7 @@ function lineoffset(framecode::FrameCode)
return offset
end

getline(ln) = isexpr(ln, :line) ? ln.args[1] : ln.line
getline(ln) = Int(isexpr(ln, :line) ? ln.args[1] : ln.line)
getfile(ln) = CodeTracking.maybe_fixup_stdlib_path(String(isexpr(ln, :line) ? ln.args[2] : ln.file))

"""
Expand All @@ -236,7 +253,7 @@ determined, `loc == nothing`. Otherwise `loc == (filepath, line)`.
function CodeTracking.whereis(framecode::FrameCode, pc)
codeloc = codelocation(framecode.src, pc)
codeloc == 0 && return nothing
lineinfo = framecode.src.linetable[codeloc]
lineinfo = linetable(framecode)[codeloc]
return isa(framecode.scope, Method) ?
whereis(lineinfo, framecode.scope) : (getfile(lineinfo), getline(lineinfo))
end
Expand All @@ -252,22 +269,22 @@ See [`CodeTracking.whereis`](@ref) for dynamic line information.
function linenumber(framecode::FrameCode, pc)
codeloc = codelocation(framecode.src, pc)
codeloc == 0 && return nothing
return getline(framecode.src.linetable[codeloc])
return getline(linetable(framecode)[codeloc])
end
linenumber(frame::Frame, pc=frame.pc) = linenumber(frame.framecode, pc)

function getfile(framecode::FrameCode, pc)
codeloc = codelocation(framecode.src, pc)
codeloc == 0 && return nothing
return getfile(framecode.src.linetable[codeloc])
return getfile(linetable(framecode)[codeloc])
end
getfile(frame::Frame, pc=frame.pc) = getfile(frame.framecode, pc)

function codelocation(code::CodeInfo, idx)
codeloc = code.codelocs[idx]
codeloc = codelocs(code)[idx]
while codeloc == 0 && (code.code[idx] === nothing || isexpr(code.code[idx], :meta)) && idx < length(code.code)
idx += 1
codeloc = code.codelocs[idx]
codeloc = codelocs(code)[idx]
end
return codeloc
end
Expand All @@ -276,7 +293,7 @@ function compute_corrected_linerange(method::Method)
_, line1 = whereis(method)
offset = line1 - method.line
src = JuliaInterpreter.get_source(method)
lastline = src.linetable[end]
lastline = linetable(src)[end]
return line1:getline(lastline) + offset
end

Expand All @@ -287,19 +304,19 @@ function method_contains_line(method::Method, line::Integer)
end

function toplevel_code_contains_line(framecode::FrameCode, line::Integer)
return getline(first(framecode.src.linetable)) <= line <= getline(last(framecode.src.linetable))
return getline(first(linetable(framecode))) <= line <= getline(last(linetable(framecode)))
end

"""
stmtidx = statementnumber(frame, line)
stmtidx = statementnumber(frame, line::Integer)
Return the index of the first statement in `frame`'s `CodeInfo` that corresponds to
static line number `line`.
"""
function statementnumber(framecode::FrameCode, line)
lineidx = searchsortedfirst(framecode.src.linetable, line; by=lin->isa(lin,Integer) ? lin : getline(lin))
1 <= lineidx <= length(framecode.src.linetable) || throw(ArgumentError("line $line not found in $(framecode.scope)"))
return searchsortedfirst(framecode.src.codelocs, lineidx)
function statementnumber(framecode::FrameCode, line::Integer)
lineidx = searchsortedfirst(linetable(framecode), line; by=lin->isa(lin,Integer) ? Int(lin) : getline(lin))::Int
1 <= lineidx <= length(linetable(framecode)) || throw(ArgumentError("line $line not found in $(framecode.scope)"))
return searchsortedfirst(codelocs(framecode), lineidx)
end
statementnumber(frame::Frame, line) = statementnumber(frame.framecode, line)

Expand Down Expand Up @@ -334,7 +351,7 @@ breakpointchar(framecode, stmtidx) =
function print_framecode(io::IO, framecode::FrameCode; pc=0, range=1:nstatements(framecode), kwargs...)
iscolor = get(io, :color, false)
ndstmt = ndigits(nstatements(framecode))
lt = framecode.src.linetable
lt = linetable(framecode)
offset = lineoffset(framecode)
ndline = isempty(lt) ? 0 : ndigits(getline(lt[end]) + offset)
nullline = " "^ndline
Expand Down

0 comments on commit ff524e2

Please sign in to comment.