Skip to content

Commit 4d38fc9

Browse files
committed
some code cleanup and improvements
1 parent 7872f10 commit 4d38fc9

File tree

15 files changed

+134
-110
lines changed

15 files changed

+134
-110
lines changed

base/Base.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ in_sysimage(pkgid::PkgId) = pkgid in _sysimage_modules
541541
for match = _methods(+, (Int, Int), -1, get_world_counter())
542542
m = match.method
543543
delete!(push!(Set{Method}(), m), m)
544-
Core.Compiler.copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(match), typemax(UInt)))
544+
copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(match), typemax(UInt)))
545545

546546
empty!(Set())
547547
push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two))

base/compiler/ssair/ir.jl

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,35 +179,44 @@ mutable struct DebugInfoStream
179179
def::Union{MethodInstance,Symbol,Nothing}
180180
linetable::Union{Nothing,Core.DebugInfo}
181181
edges::Vector{Any} # Vector{Core.DebugInfo}
182+
firstline::Int32 # the starting line for this block (specified by having an index of 0)
182183
codelocs::Vector{Int32} # for each statement:
183184
# index into linetable (if defined), else a line number (in the file represented by def)
184185
# then index into edges
185186
# then index into edges[linetable]
186-
function DebugInfoStream(def::Union{MethodInstance,Nothing}, linetable::Union{Nothing,DebugInfo}, edges::Vector{Any}, codelocs::Vector{Int32})
187-
return new(def, linetable, edges, codelocs)
187+
function DebugInfoStream(codelocs::Vector{Int32})
188+
return new(nothing, nothing, [], 0, codelocs)
188189
end
189190
#DebugInfoStream(def::Union{MethodInstance,Nothing}, di::DebugInfo, nstmts::Int) =
190191
# if debuginfo_file1(di.def) === debuginfo_file1(di.def)
191-
# new(def, di.linetable, Core.svec(di.edges...),
192-
# ccall(:jl_uncompress_codelocs, Any, (Any, Int), di.codelocs, nstmts))
192+
# new(def, di.linetable, Core.svec(di.edges...), getdebugidx(di, 0),
193+
# ccall(:jl_uncompress_codelocs, Any, (Any, Int), di.codelocs, nstmts)::Vector{Int32})
193194
# else
194195
function DebugInfoStream(def::Union{MethodInstance,Nothing}, di::DebugInfo, nstmts::Int)
195196
codelocs = zeros(Int32, nstmts * 3)
196197
for i = 1:nstmts
197198
codelocs[3i - 2] = i
198199
end
199-
return new(def, di, Vector{Any}(), codelocs)
200+
return new(def, di, Vector{Any}(), 0, codelocs)
200201
end
201-
global copy(di::DebugInfoStream) = new(di.def, di.linetable, di.edges, di.codelocs)
202+
global copy(di::DebugInfoStream) = new(di.def, di.linetable, di.edges, di.firstline, di.codelocs)
202203
end
203204

204205
Core.DebugInfo(di::DebugInfoStream, nstmts::Int) =
205206
Core.DebugInfo(something(di.def), di.linetable, Core.svec(di.edges...),
206-
ccall(:jl_compress_codelocs, Any, (Any, Int), di.codelocs, nstmts)::String)
207+
ccall(:jl_compress_codelocs, Any, (Int32, Any, Int), di.firstline, di.codelocs, nstmts)::String)
207208

208-
getdebugidx(debuginfo::Core.DebugInfo, pc::Int) = ccall(:jl_uncompress1_codeloc, NTuple{3,Int32}, (Any, Int), debuginfo.codelocs, (pc - 1))
209-
getdebugidx(debuginfo::DebugInfoStream, pc::Int) =
210-
3 <= 3pc <= length(debuginfo.codelocs) ? (debuginfo.codelocs[3pc - 2], debuginfo.codelocs[3pc - 1], debuginfo.codelocs[3pc - 0]) : (Int32(-1), Int32(0), Int32(0))
209+
getdebugidx(debuginfo::Core.DebugInfo, pc::Int) = ccall(:jl_uncompress1_codeloc, NTuple{3,Int32}, (Any, Int), debuginfo.codelocs, pc)
210+
211+
function getdebugidx(debuginfo::DebugInfoStream, pc::Int)
212+
if 3 <= 3pc <= length(debuginfo.codelocs)
213+
return (debuginfo.codelocs[3pc - 2], debuginfo.codelocs[3pc - 1], debuginfo.codelocs[3pc - 0])
214+
elseif pc == 0
215+
return (Int32(debuginfo.firstline), Int32(0), Int32(0))
216+
else
217+
return (Int32(-1), Int32(0), Int32(0))
218+
end
219+
end
211220

212221

213222
# SSA values that need renaming
@@ -446,7 +455,7 @@ from the frontend or one of the caches.
446455
"""
447456
function IRCode()
448457
stmts = InstructionStream(1)
449-
debuginfo = DebugInfoStream(nothing, nothing, Any[], stmts.line)
458+
debuginfo = DebugInfoStream(stmts.line)
450459
stmts.line[1] = 1
451460
ir = IRCode(stmts, CFG([BasicBlock(1:1, Int[], Int[])], Int[1]), debuginfo, Any[], Expr[], VarState[])
452461
ir[SSAValue(1)][:stmt] = ReturnNode(nothing)

base/compiler/ssair/show.jl

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -341,42 +341,16 @@ function debuginfo_file1(debuginfo::Union{Core.DebugInfo,DebugInfoStream})
341341
return :var"<unknown>"
342342
end
343343

344-
# utility function to extract the file name from a DebugInfo object
345-
function debuginfo_file(debuginfo::Union{Core.DebugInfo,DebugInfoStream})
346-
linetable = debuginfo.linetable
347-
while linetable != nothing
348-
debuginfo = linetable
349-
linetable = debuginfo.linetable
350-
end
351-
return debuginfo_file1(debuginfo)
352-
end
353-
354-
# utility function to extract the first line number of a block of code (corresponding to debuginfo_file)
344+
# utility function to extract the first line number and file of a block of code
355345
function debuginfo_firstline(debuginfo::Union{Core.DebugInfo,DebugInfoStream})
356346
linetable = debuginfo.linetable
357347
while linetable != nothing
358348
debuginfo = linetable
359349
linetable = debuginfo.linetable
360350
end
361-
codeloc = getdebugidx(debuginfo, 1)
362-
return codeloc[1]
363-
end
364-
365-
## utility function to extract the line number at a particular program counter (ignoring inlining)
366-
## corresponds to debuginfo_file. return <= 0 if there is no line number change caused by this statement
367-
function debuginfo_line(debuginfo::Union{Core.DebugInfo,DebugInfoStream}, pc::Int)
368-
while pc > 0
369-
codeloc = getdebugidx(debuginfo, pc)
370-
pc::Int = codeloc[1]
371-
debuginfo = debuginfo.linetable
372-
if debuginfo === nothing || pc <= 0
373-
return pc
374-
end
375-
end
376-
return -1
351+
codeloc = getdebugidx(debuginfo, 0)
352+
return debuginfo_file1(debuginfo), codeloc[1]
377353
end
378-
## alternative definition of debuginfo_firstline which gets the line for the first existing pc, rather that the first line
379-
#debuginfo_firstline(debuginfo::Union{Core.DebugInfo,DebugInfoStream}) = deubginfo_line(debuginfo, 1)
380354

381355
struct LineInfoNode
382356
method # ::Union{Method,MethodInstance,Symbol}

base/compiler/ssair/verify.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -384,12 +384,10 @@ end
384384

385385
function verify_linetable(di::DebugInfoStream, nstmts::Int, print::Bool=true)
386386
@assert 3nstmts == length(di.codelocs)
387-
# jwn
388-
#for i in 1:nstmts
389-
# @assert di.codelocs[3i-2] <= length(di.linetable)
390-
# di.codelocs[3i-2] == 0 && continue
391-
# @assert di.codelocs[3i-1] <= length(di.edges)
392-
# di.codelocs[3i-1] == 0 && continue
393-
# @assert di.codelocs[3i-0] <= length(di.edges[di.codelocs[3i-1]].linetable)
394-
#end
387+
for i in 1:nstmts
388+
edge = di.codelocs[3i-1]
389+
if !(edge == 0 || get(di.edges, edge, nothing) isa DebugInfo)
390+
@verify_error "Malformed debuginfo index into edges"
391+
end
392+
end
395393
end

base/show.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,8 @@ function show_mi(io::IO, l::Core.MethodInstance, from_stackframe::Bool=false)
13391339
# to print a little more identifying information.
13401340
if !from_stackframe
13411341
di = mi.uninferred.debuginfo
1342-
file, line = string(IRShow.debuginfo_file(di)), IRShow.debuginfo_firstline(di)
1342+
file, line = IRShow.debuginfo_firstline(di)
1343+
file = string(file)
13431344
line = isempty(file) || line < 0 ? "<unknown>" : "$file:$line"
13441345
print(io, " from ", def, " starting at ", line)
13451346
end
@@ -1364,7 +1365,8 @@ function show(io::IO, mi_info::Core.Compiler.Timings.InferenceFrameInfo)
13641365
end
13651366
else
13661367
di = mi.uninferred.debuginfo
1367-
file, line = string(IRShow.debuginfo_file(di)), IRShow.debuginfo_firstline(di)
1368+
file, line = IRShow.debuginfo_firstline(di)
1369+
file = string(file)
13681370
line = isempty(file) || line < 0 ? "<unknown>" : "$file:$line"
13691371
print(io, "Toplevel InferenceFrameInfo thunk from ", def, " starting at ", line)
13701372
end

base/stacktraces.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ function lookup(ip::Union{Base.InterpreterIP,Core.Compiler.InterpreterIP})
143143
file = empty_sym
144144
line = Int32(0)
145145
end
146-
pc::Int = max(ip.stmt, 0) # n.b. ip.stmt is 0-indexed
146+
pc::Int = max(ip.stmt + 1, 0) # n.b. ip.stmt is 0-indexed
147147
debuginfo = codeinfo.debuginfo
148148
codeloc = @ccall jl_uncompress1_codeloc(debuginfo.codelocs::Any, pc::Int)::NTuple{3,Int32}
149149
if (codeloc[1] == 0 && codeloc[2] == 0) || codeloc[1] < 0
@@ -157,8 +157,8 @@ function lookup(ip::Union{Base.InterpreterIP,Core.Compiler.InterpreterIP})
157157
debuginfo.def isa Symbol || (def = debuginfo.def)
158158
codeloc = @ccall jl_uncompress1_codeloc(debuginfo.codelocs::Any, pc::Int)::NTuple{3,Int32}
159159
line = codeloc[1]
160-
line < 0 && (line = 0) # broken debug info?
161-
if debuginfo.linetable === nothing || line == 0
160+
if debuginfo.linetable === nothing || pc <= 0 || line < 0
161+
line < 0 && (line = 0) # broken debug info?
162162
push!(scopes, StackFrame(normalize_method_name(def), debuginfo_file1(debuginfo), line, inlined ? nothing : code, false, inlined, 0))
163163
else
164164
append_scopes!(scopes, line - 1, debuginfo.linetable::Core.DebugInfo, def, inlined)
@@ -169,8 +169,6 @@ function lookup(ip::Union{Base.InterpreterIP,Core.Compiler.InterpreterIP})
169169
inl_to == 0 && break
170170
debuginfo = debuginfo.edges[inl_to]
171171
pc::Int = codeloc[3]
172-
pc == 0 && break # TODO: use toplevel line?
173-
pc -= 1
174172
end
175173
end
176174
append_scopes!(scopes, pc, debuginfo, def, false)

doc/src/devdocs/ast.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ mutable struct DebugInfoStream
779779
def::Union{Method,MethodInstance,Symbol}
780780
linetable::Union{Nothing,DebugInfo}
781781
edges::Vector{DebugInfo}
782+
firstline::Int32 # the starting line for this block (specified by an index of 0)
782783
codelocs::Vector{Int32} # for each statement:
783784
# index into linetable (if defined), else a line number (in the file represented by def)
784785
# then index into edges
@@ -793,15 +794,30 @@ end
793794

794795
Another debuginfo that this was derived from. If `def` is not a Symbol, then it replaces
795796
the current function for metadata. The codelocs line number also becomes an index into
796-
this codelocs instead of being a line number itself (including its edges).
797+
this codelocs instead of being a line number itself, as described below.
797798

798-
* `edges` : Vector of unique DebugInfo for every inlined function
799+
* `edges` : Vector of the unique DebugInfo for every inlined function
800+
801+
* `firstline` (when uncompressed to DebugInfoStream)
802+
803+
The line number associated with the `begin` statement (or other keyword such as
804+
`function` or `quote`) that delinated where this code definition "starts".
799805

800806
* `codelocs` (when uncompressed to DebugInfoStream)
801807

802-
A vector of indicies, with 3 values for each statement in the IR, that describe the stacktrace from that point:
803-
- the integer index into the `linetable`, giving the original location associated with each statement.
808+
A vector of indices, with 3 values for each statement in the IR plus one for the
809+
starting point of the block, that describe the stacktrace from that point:
810+
1. the integer index into the `linetable.codelocs` field, giving the original location
811+
associated with each statement (including its edges), or zero indicating to use
812+
`linetable.firstline` as the line number.
804813
or
805814
the line number itself if the `linetable` field is `nothing`
806-
- the integer index into edges, giving the DebugInfo inlined there.
807-
- the integer index into edges[codelocs], giving the recursion point.
815+
2. the integer index into edges, giving the DebugInfo inlined there (or zero if there
816+
are no edges).
817+
3. (if entry 2 is non-zero) the integer index into edges[].codelocs, giving the
818+
recursion point, or zero indicating to use `edges[].firstline` as the line number.
819+
820+
Special codes include:
821+
- (zero, zero, *) : no change to the line number or edges
822+
- (zero, *, *) : no line number, just edges (usually because of macro-expansion into
823+
top-level code)

src/codegen.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7588,19 +7588,13 @@ static jl_llvm_functions_t
75887588
ctx.file = jl_symbol_name(lam->def.method->file);
75897589
}
75907590
else if ((jl_value_t*)src->debuginfo != jl_nothing) {
7591-
// look for the file and line info of the first actual statement
7592-
// as sometimes lowering emits inlining info that we want to ignore
7591+
// look for the file and line info of the original start of this block, as reported by lowering
75937592
jl_debuginfo_t *debuginfo = src->debuginfo;
7593+
while ((jl_value_t*)debuginfo->linetable != jl_nothing)
7594+
debuginfo = debuginfo->linetable;
75947595
ctx.file = jl_debuginfo_file(debuginfo);
7595-
if (jl_array_nrows(debuginfo->codelocs) > 0) {
7596-
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, 0);
7597-
jl_debuginfo_t *linetable = debuginfo->linetable;
7598-
while (lineidx.line > 0 && (jl_value_t*)linetable != jl_nothing) {
7599-
lineidx = jl_uncompress1_codeloc(linetable->codelocs, lineidx.line - 1);
7600-
linetable = linetable->linetable;
7601-
}
7602-
toplineno = std::max((int32_t)0, lineidx.line);
7603-
}
7596+
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, 0);
7597+
toplineno = std::max((int32_t)0, lineidx.line);
76047598
}
76057599
if (ctx.file.empty())
76067600
ctx.file = "<missing>";
@@ -8340,27 +8334,25 @@ static jl_llvm_functions_t
83408334
new_lineinfo.push_back(topinfo);
83418335
auto update_lineinfo = [&] (size_t pc) {
83428336
jl_debuginfo_t *debuginfo = src->debuginfo;
8343-
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, pc);
8337+
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, pc + 1);
83448338
if (lineidx.line == 0 && lineidx.to == 0)
83458339
return false; // do not change anything
83468340
prev_lineinfo.resize(0);
83478341
std::swap(prev_lineinfo, new_lineinfo);
8348-
std::function<void(jl_debuginfo_t *debuginfo, jl_value_t *func, size_t to, size_t pc)> append_lineinfo =
8342+
std::function<void(jl_debuginfo_t*, jl_value_t*, size_t, size_t)> append_lineinfo =
83498343
[&] (jl_debuginfo_t *debuginfo, jl_value_t *func, size_t to, size_t pc) -> void {
83508344
while (1) {
8351-
if (pc + 1 == 0)
8352-
break; // TODO: this should be the toplevel node
83538345
if (!jl_is_symbol(debuginfo->def)) // this is a path
83548346
func = debuginfo->def; // this is inlined
83558347
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, pc);
83568348
size_t i = lineidx.line;
8357-
if (i < 0)
8358-
i = 0; // pc out of range: broken debuginfo?
8359-
if (i > 0 && (jl_value_t*)debuginfo->linetable != jl_nothing) {
8349+
if (pc > 0 && i >= 0 && (jl_value_t*)debuginfo->linetable != jl_nothing) {
83608350
// indirection node
8361-
append_lineinfo(debuginfo->linetable, func, to, i - 1);
8351+
append_lineinfo(debuginfo->linetable, func, to, i);
83628352
}
83638353
else {
8354+
if (i < 0)
8355+
i = 0; // pc out of range: broken debuginfo?
83648356
// actual node
83658357
DebugLineTable info;
83668358
info.edgeid = to;
@@ -8407,12 +8399,12 @@ static jl_llvm_functions_t
84078399
to = lineidx.to;
84088400
if (to == 0)
84098401
break;
8410-
pc = lineidx.pc - 1;
8402+
pc = lineidx.pc;
84118403
debuginfo = (jl_debuginfo_t*)jl_svecref(debuginfo->edges, to - 1);
84128404
func = NULL;
84138405
}
84148406
};
8415-
append_lineinfo(debuginfo, (jl_value_t*)lam, 0, pc);
8407+
append_lineinfo(debuginfo, (jl_value_t*)lam, 0, pc + 1);
84168408
assert(new_lineinfo.size() > 0);
84178409
return true;
84188410
};
@@ -8570,10 +8562,21 @@ static jl_llvm_functions_t
85708562
bool is_tracked = in_tracked_path(file);
85718563
if (do_coverage(is_user_code, is_tracked)) {
85728564
for (size_t pc = 0; 1; pc++) {
8573-
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, pc);
8565+
struct jl_codeloc_t lineidx = jl_uncompress1_codeloc(debuginfo->codelocs, pc + 1);
85748566
if (lineidx.line == -1)
85758567
break;
8576-
jl_coverage_alloc_line(file, lineidx.line);
8568+
jl_debuginfo_t *linetable = debuginfo->linetable;
8569+
while (lineidx.line >= 0 && (jl_value_t*)linetable != jl_nothing) {
8570+
if (lineidx.line == 0) {
8571+
lineidx = jl_uncompress1_codeloc(linetable->codelocs, lineidx.line);
8572+
break;
8573+
}
8574+
lineidx = jl_uncompress1_codeloc(linetable->codelocs, lineidx.line);
8575+
linetable = linetable->linetable;
8576+
}
8577+
if (lineidx.line > 0) {
8578+
jl_coverage_alloc_line(file, lineidx.line);
8579+
}
85778580
}
85788581
}
85798582
};

0 commit comments

Comments
 (0)