@@ -97,87 +97,6 @@ function hash(frame::StackFrame, h::UInt)
97
97
return h
98
98
end
99
99
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
-
181
100
"""
182
101
lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}
183
102
@@ -189,25 +108,11 @@ Base.@constprop :none function lookup(pointer::Ptr{Cvoid})
189
108
infos = ccall (:jl_lookup_code_address , Any, (Ptr{Cvoid}, Cint), pointer, false ):: Core.SimpleVector
190
109
pointer = convert (UInt64, pointer)
191
110
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
195
111
res = Vector {StackFrame} (undef, length (infos))
196
- for i in reverse ( 1 : length (infos) )
112
+ for i in 1 : length (infos)
197
113
info = infos[i]:: Core.SimpleVector
198
114
@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)
211
116
end
212
117
return res
213
118
end
0 commit comments