Skip to content

Commit c3739d1

Browse files
authored
Merge pull request #675 from JuliaDebug/teh/llvmcall_ega
Try harder to find llvmcalls
2 parents 890cae3 + b5340fd commit c3739d1

File tree

5 files changed

+19
-4
lines changed

5 files changed

+19
-4
lines changed

src/commands.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ function finish_stack!(@nospecialize(recurse), frame::Frame, rootistoplevel::Boo
7474
end
7575
end
7676
pc += 1
77+
@assert is_leaf(frame)
7778
frame.pc = pc
7879
shouldbreak(frame, pc) && return BreakpointRef(frame.framecode, pc)
7980
end
@@ -410,6 +411,7 @@ function unwind_exception(frame::Frame, @nospecialize(exc))
410411
while frame !== nothing
411412
if !isempty(frame.framedata.exception_frames)
412413
# Exception caught
414+
@assert is_leaf(frame)
413415
frame.pc = frame.framedata.exception_frames[end]
414416
frame.framedata.last_exception[] = exc
415417
return frame

src/construct.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ end
4848
end
4949

5050
function return_from(frame::Frame)
51-
recycle(frame)
51+
oldframe = frame
5252
frame = caller(frame)
53+
recycle(oldframe)
5354
frame === nothing || (frame.callee = nothing)
5455
return frame
5556
end
@@ -166,8 +167,8 @@ function prepare_framecode(method::Method, @nospecialize(argtypes); enter_genera
166167
# Currenly, our strategy to deal with llvmcall can't handle parametric functions
167168
# (the "mini interpreter" runs in module scope, not method scope)
168169
if (!isempty(lenv) && (hasarg(isidentical(:llvmcall), code.code) ||
169-
hasarg(isidentical(Base.llvmcall), code.code) ||
170-
hasarg(a->is_global_ref(a, Base, :llvmcall), code.code))) ||
170+
hasarg(isidentical(Core.Intrinsics.llvmcall), code.code) ||
171+
hasarg(a->is_global_ref_egal(a, :llvmcall, Core.Intrinsics.llvmcall), code.code))) ||
171172
hasarg(isidentical(:iolock_begin), code.code)
172173
return Compiled()
173174
end

src/interpret.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,13 +560,15 @@ function step_expr!(@nospecialize(recurse), frame::Frame, @nospecialize(node), i
560560
rhs = eval_rhs(recurse, frame, node)
561561
end
562562
elseif isa(node, GotoNode)
563+
@assert is_leaf(frame)
563564
return (frame.pc = node.label)
564565
elseif isa(node, GotoIfNot)
565566
arg = @lookup(frame, node.cond)
566567
if !isa(arg, Bool)
567568
throw(TypeError(nameof(frame), "if", Bool, arg))
568569
end
569570
if !arg
571+
@assert is_leaf(frame)
570572
return (frame.pc = node.dest)
571573
end
572574
elseif isa(node, ReturnNode)
@@ -596,6 +598,7 @@ function step_expr!(@nospecialize(recurse), frame::Frame, @nospecialize(node), i
596598
lhs = SSAValue(pc)
597599
do_assignment!(frame, lhs, rhs)
598600
end
601+
@assert is_leaf(frame)
599602
return (frame.pc = pc + 1)
600603
end
601604

@@ -653,6 +656,7 @@ function handle_err(@nospecialize(recurse), frame::Frame, @nospecialize(err))
653656
end
654657
data.last_exception[] = err
655658
pc = @static VERSION >= v"1.11-" ? pop!(data.exception_frames) : data.exception_frames[end] # implicit :leave after https://github.com/JuliaLang/julia/pull/52245
659+
@assert is_leaf(frame)
656660
frame.pc = pc
657661
return pc
658662
end

src/optimize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ function optimize!(code::CodeInfo, scope)
131131
# Check for :llvmcall
132132
arg1 = stmt.args[1]
133133
larg1 = lookup_stmt(code.code, arg1)
134-
if (arg1 === :llvmcall || larg1 === Base.llvmcall || is_global_ref(larg1, Base, :llvmcall)) && isempty(sparams) && scope isa Method
134+
if (arg1 === :llvmcall || larg1 === Base.llvmcall || is_global_ref_egal(larg1, :llvmcall, Core.Intrinsics.llvmcall)) && isempty(sparams) && scope isa Method
135135
# Call via `invokelatest` to avoid compiling it until we need it
136136
@invokelatest build_compiled_llvmcall!(stmt, code, idx, evalmod)
137137
methodtables[idx] = Compiled()

src/utils.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ Tests whether `g` is equal to `GlobalRef(mod, name)`.
140140
"""
141141
is_global_ref(@nospecialize(g), mod::Module, name::Symbol) = isa(g, GlobalRef) && g.mod === mod && g.name == name
142142

143+
function is_global_ref_egal(@nospecialize(g), name::Symbol, @nospecialize(ref))
144+
# Identifying GlobalRefs regardless of how the caller scopes them
145+
isa(g, GlobalRef) || return false
146+
g.name === name || return false
147+
gref = getglobal(g.mod, g.name)
148+
return gref === ref
149+
end
150+
143151
is_quotenode(@nospecialize(q), @nospecialize(val)) = isa(q, QuoteNode) && q.value == val
144152
is_quotenode_egal(@nospecialize(q), @nospecialize(val)) = isa(q, QuoteNode) && q.value === val
145153

0 commit comments

Comments
 (0)