From ad792afcb320971231128479cff9baa3bd1245d0 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sat, 15 Oct 2022 10:14:08 -0500 Subject: [PATCH] Update invalidation logging format (#306) This updates to the logging format used by the most recent nightly build of Julia (1.9). While there has been a lot of churn in this area, there are reasons to hope that we're entering a period of stability: there are no known "holes" in our coverage after resolving the `invoke` issues (https://github.com/JuliaLang/julia/pull/46010 and fixup PRs that came later), and the subsequent major rewrite of the invalidation logic during deserialization (https://github.com/JuliaLang/julia/pull/46920) suggests this format may have some durability. Co-authored-by: Rik Huijzer --- Project.toml | 2 +- SnoopPrecompile/test/runtests.jl | 2 +- src/invalidations.jl | 50 ++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index e5bbe89a..c05850af 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SnoopCompile" uuid = "aa65fe97-06da-5843-b5b1-d5d13cad87d2" author = ["Tim Holy "] -version = "2.9.4" +version = "2.9.5" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/SnoopPrecompile/test/runtests.jl b/SnoopPrecompile/test/runtests.jl index 6239c29d..e4d536c2 100644 --- a/SnoopPrecompile/test/runtests.jl +++ b/SnoopPrecompile/test/runtests.jl @@ -47,6 +47,6 @@ using UUIDs end close(pipe.in) str = read(pipe.out, String) - @test occursin("UndefVarError: missing_function not defined", str) + @test occursin(r"UndefVarError: `?missing_function`? not defined", str) end end diff --git a/src/invalidations.jl b/src/invalidations.jl index 4f5fbf4c..1e5fe348 100644 --- a/src/invalidations.jl +++ b/src/invalidations.jl @@ -63,8 +63,8 @@ mutable struct InstanceNode end InstanceNode(mi::MethodInstance, children::Vector{InstanceNode}) = return new(mi, 0, children) # Create child with a given `parent`. Checks that the depths are consistent. - function InstanceNode(mi::MethodInstance, parent::InstanceNode, depth) - @assert parent.depth + Int32(1) == depth + function InstanceNode(mi::MethodInstance, parent::InstanceNode, depth=parent.depth+Int32(1)) + depth !== nothing && @assert parent.depth + Int32(1) == depth child = new(mi, depth, InstanceNode[], parent) push!(parent.children, child) return child @@ -249,6 +249,12 @@ function showlist(io::IO, treelist, indent::Int=0) end end +if Base.VERSION >= v"1.9.0-DEV.1512" + new_backedge_table() = Dict{Union{Int32,MethodInstance},Union{Tuple{Any,Vector{Any}},InstanceNode}}() +else + new_backedge_table() = Dict{Tuple{Int32,UInt64},Tuple{Any,Vector{Any}}}() +end + """ trees = invalidation_trees(list) @@ -288,6 +294,11 @@ See the documentation for further details. function invalidation_trees(list; exclude_corecompiler::Bool=true) function handle_insert_backedges(list, i, callee) + if Base.VERSION >= v"1.9.0-DEV.1512" + key, causes = list[i+=1], list[i+=1] + backedge_table[key] = (callee, causes) + return i + end if Base.VERSION >= v"1.9.0-DEV.1432" key = (list[i+=1], list[i+=1]) backedge_table[key] = (callee, list[i+=1]) @@ -316,7 +327,7 @@ function invalidation_trees(list; exclude_corecompiler::Bool=true) leaf = nothing mt_backedges, backedges, mt_cache, mt_disable = methinv_storage() reason = nothing - backedge_table = Dict{Tuple{Int32,UInt64},Tuple{Any,Vector{Any}}}() + backedge_table = new_backedge_table() i = 0 while i < length(list) item = list[i+=1] @@ -337,6 +348,9 @@ function invalidation_trees(list; exclude_corecompiler::Bool=true) end elseif isa(item, String) loctag = item + if Base.VERSION >= v"1.9.0-DEV.1512" && loctag ∉ ("insert_backedges_callee", "verify_methods") + empty!(backedge_table) + end if loctag == "invalidate_mt_cache" push!(mt_cache, mi) leaf = nothing @@ -371,6 +385,36 @@ function invalidation_trees(list; exclude_corecompiler::Bool=true) end elseif loctag == "insert_backedges_callee" i = handle_insert_backedges(list, i, mi) + elseif loctag == "verify_methods" + next = list[i+=1] + if isa(next, Integer) + trig, causes = backedge_table[next] + newnode = InstanceNode(mi, 1) + push!(mt_backedges, trig => newnode) + backedge_table[mi] = newnode + for cause in causes + add_method_trigger!(methodinvs, cause, :inserting, mt_backedges, backedges, mt_cache, mt_disable) + end + mt_backedges, backedges, mt_cache, mt_disable = methinv_storage() + leaf = nothing + reason = nothing + else + @assert isa(next, MethodInstance) "unexpected logging format" + parent = backedge_table[next] + found = false + for child in parent.children + if child.mi == mi + found = true + break + end + end + if !found + newnode = InstanceNode(mi, parent) + if !haskey(backedge_table, mi) + backedge_table[mi] = newnode + end + end + end elseif loctag == "insert_backedges" if Base.VERSION >= v"1.9.0-DEV.1432" key = (list[i+=1], list[i+=1])