@@ -97,87 +97,6 @@ function hash(frame::StackFrame, h::UInt)
9797 return h
9898end
9999
100- get_inlinetable (:: Any ) = nothing
101- function get_inlinetable (mi:: MethodInstance )
102- isdefined (mi, :def ) && mi. def isa Method && isdefined (mi, :cache ) && isdefined (mi. cache, :inferred ) &&
103- mi. cache. inferred != = nothing || return nothing
104- linetable = ccall (:jl_uncompress_ir , Any, (Any, Any, Any), mi. def, mi. cache, mi. cache. inferred). linetable
105- return filter! (x -> x. inlined_at > 0 , linetable)
106- end
107-
108- get_method_instance_roots (:: Any ) = nothing
109- function get_method_instance_roots (mi:: Union{Method, MethodInstance} )
110- m = mi isa MethodInstance ? mi. def : mi
111- m isa Method && isdefined (m, :roots ) || return nothing
112- return filter (x -> x isa MethodInstance, m. roots)
113- end
114-
115- function lookup_inline_frame_info (func:: Symbol , file:: Symbol , linenum:: Int , inlinetable:: Vector{Core.LineInfoNode} )
116- # REPL frames and some base files lack this prefix while others have it; should fix?
117- filestripped = Symbol (lstrip (string (file), (' .' , ' \\ ' , ' /' )))
118- linfo = nothing
119- #=
120- Some matching entries contain the MethodInstance directly.
121- Other matching entries contain only a Method or Symbol (function name); such entries
122- are located after the entry with the MethodInstance, so backtracking is required.
123- If backtracking fails, the Method or Module is stored for return, but we continue
124- the search in case a MethodInstance is found later.
125- TODO : If a backtrack has failed, do we need to backtrack again later if another Method
126- or Symbol match is found? Or can a limit on the subsequent backtracks be placed?
127- =#
128- for (i, line) in enumerate (inlinetable)
129- Base. IRShow. method_name (line) === func && line. file ∈ (file, filestripped) && line. line == linenum || continue
130- if line. method isa MethodInstance
131- linfo = line. method
132- break
133- elseif line. method isa Method || line. method isa Symbol
134- linfo = line. method isa Method ? line. method : line. module
135- # backtrack to find the matching MethodInstance, if possible
136- for j in (i - 1 ): - 1 : 1
137- nextline = inlinetable[j]
138- nextline. inlined_at == line. inlined_at && Base. IRShow. method_name (line) === Base. IRShow. method_name (nextline) && line. file === nextline. file || break
139- if nextline. method isa MethodInstance
140- linfo = nextline. method
141- break
142- end
143- end
144- end
145- end
146- return linfo
147- end
148-
149- function lookup_inline_frame_info (func:: Symbol , file:: Symbol , miroots:: Vector{Any} )
150- # REPL frames and some base files lack this prefix while others have it; should fix?
151- filestripped = Symbol (lstrip (string (file), (' .' , ' \\ ' , ' /' )))
152- matches = filter (miroots) do x
153- x. def isa Method || return false
154- m = x. def:: Method
155- return m. name == func && m. file ∈ (file, filestripped)
156- end
157- if length (matches) > 1
158- # ambiguous, check if method is same and return that instead
159- all_matched = true
160- for m in matches
161- all_matched = m. def. line == matches[1 ]. def. line &&
162- m. def. module == matches[1 ]. def. module
163- all_matched || break
164- end
165- if all_matched
166- return matches[1 ]. def
167- end
168- # all else fails, return module if they match, or give up
169- all_matched = true
170- for m in matches
171- all_matched = m. def. module == matches[1 ]. def. module
172- all_matched || break
173- end
174- return all_matched ? matches[1 ]. def. module : nothing
175- elseif length (matches) == 1
176- return matches[1 ]
177- end
178- return nothing
179- end
180-
181100"""
182101 lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}
183102
@@ -189,25 +108,11 @@ Base.@constprop :none function lookup(pointer::Ptr{Cvoid})
189108 infos = ccall (:jl_lookup_code_address , Any, (Ptr{Cvoid}, Cint), pointer, false ):: Core.SimpleVector
190109 pointer = convert (UInt64, pointer)
191110 isempty (infos) && return [StackFrame (empty_sym, empty_sym, - 1 , nothing , true , false , pointer)] # this is equal to UNKNOWN
192- parent_linfo = infos[end ][4 ]
193- inlinetable = get_inlinetable (parent_linfo)
194- miroots = inlinetable === nothing ? get_method_instance_roots (parent_linfo) : nothing # fallback if linetable missing
195111 res = Vector {StackFrame} (undef, length (infos))
196- for i in reverse ( 1 : length (infos) )
112+ for i in 1 : length (infos)
197113 info = infos[i]:: Core.SimpleVector
198114 @assert (length (info) == 6 )
199- func = info[1 ]:: Symbol
200- file = info[2 ]:: Symbol
201- linenum = info[3 ]:: Int
202- linfo = info[4 ]
203- if i < length (infos)
204- if inlinetable != = nothing
205- linfo = lookup_inline_frame_info (func, file, linenum, inlinetable)
206- elseif miroots != = nothing
207- linfo = lookup_inline_frame_info (func, file, miroots)
208- end
209- end
210- res[i] = StackFrame (func, file, linenum, linfo, info[5 ]:: Bool , info[6 ]:: Bool , pointer)
115+ res[i] = StackFrame (info[1 ]:: Symbol , info[2 ]:: Symbol , info[3 ]:: Int , info[4 ], info[5 ]:: Bool , info[6 ]:: Bool , pointer)
211116 end
212117 return res
213118end
0 commit comments