diff --git a/Project.toml b/Project.toml index ec5c5aed..d97a4017 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SnoopCompile" uuid = "aa65fe97-06da-5843-b5b1-d5d13cad87d2" author = ["Tim Holy "] -version = "2.7.0" +version = "2.7.1" [deps] Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f" @@ -21,7 +21,7 @@ Cthulhu = "1.5, 2" FlameGraphs = "0.2" OrderedCollections = "1" Requires = "1" -SnoopCompileCore = "~2.7.0" +SnoopCompileCore = "~2.7.1" YAML = "0.4" julia = "1" diff --git a/SnoopCompileCore/Project.toml b/SnoopCompileCore/Project.toml index 230ad0e0..e40264f5 100644 --- a/SnoopCompileCore/Project.toml +++ b/SnoopCompileCore/Project.toml @@ -1,7 +1,7 @@ name = "SnoopCompileCore" uuid = "e2b509da-e806-4183-be48-004708413034" author = ["Tim Holy "] -version = "2.7.0" +version = "2.7.1" [deps] Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" diff --git a/src/invalidations.jl b/src/invalidations.jl index 7b4b3799..839b83d6 100644 --- a/src/invalidations.jl +++ b/src/invalidations.jl @@ -136,8 +136,9 @@ struct MethodInvalidations mt_backedges::Vector{Pair{Any,InstanceNode}} # sig=>root backedges::Vector{InstanceNode} mt_cache::Vector{MethodInstance} + mt_disable::Vector{MethodInstance} end -methinv_storage() = Pair{Any,InstanceNode}[], InstanceNode[], MethodInstance[] +methinv_storage() = Pair{Any,InstanceNode}[], InstanceNode[], MethodInstance[], MethodInstance[] function MethodInvalidations(method::Method, reason::Symbol) MethodInvalidations(method, reason, methinv_storage()...) end @@ -211,6 +212,13 @@ function Base.show(io::IO, methinvs::MethodInvalidations) print(io, indent, "backedges: ") showlist(io, methinvs.backedges, length(indent)+length("backedges")+2) end + if !isempty(methinvs.mt_disable) + print(io, indent, "mt_disable: ") + println(io, first(methinvs.mt_disable)) + if length(methinvs.mt_disable) > 1 + println(io, indent + " "^12, "+", length(methinvs.mt_disable)-1, " more") + end + end if !isempty(methinvs.mt_cache) println(io, indent, length(methinvs.mt_cache), " mt_cache") end @@ -269,7 +277,7 @@ function invalidation_trees(list; exclude_corecompiler::Bool=true) methodinvs = MethodInvalidations[] leaf = nothing - mt_backedges, backedges, mt_cache = methinv_storage() + mt_backedges, backedges, mt_cache, mt_disable = methinv_storage() reason = nothing i = 0 while i < length(list) @@ -302,12 +310,16 @@ function invalidation_trees(list; exclude_corecompiler::Bool=true) end leaf = nothing elseif loctag == "jl_method_table_disable" - root = getroot(leaf) - root.mi = mi - if !exclude_corecompiler || !from_corecompiler(mi) - push!(backedges, root) + if leaf === nothing + push!(mt_disable, mi) + else + root = getroot(leaf) + root.mi = mi + if !exclude_corecompiler || !from_corecompiler(mi) + push!(backedges, root) + end + leaf = nothing end - leaf = nothing elseif loctag == "insert_backedges" println("insert_backedges for ", mi) else @@ -322,8 +334,8 @@ function invalidation_trees(list; exclude_corecompiler::Bool=true) item = list[i+=1] if isa(item, String) reason = checkreason(reason, item) - push!(methodinvs, sort!(MethodInvalidations(method, reason, mt_backedges, backedges, mt_cache))) - mt_backedges, backedges, mt_cache = methinv_storage() + push!(methodinvs, sort!(MethodInvalidations(method, reason, mt_backedges, backedges, mt_cache, mt_disable))) + mt_backedges, backedges, mt_cache, mt_disable = methinv_storage() leaf = nothing reason = nothing else @@ -390,7 +402,7 @@ function filtermod(mod::Module, methinvs::MethodInvalidations; recursive::Bool=f end mt_backedges = filter(pr->hasmod(mod, pr.second), methinvs.mt_backedges) backedges = filter(root->hasmod(mod, root), methinvs.backedges) - return MethodInvalidations(methinvs.method, methinvs.reason, mt_backedges, backedges, copy(methinvs.mt_cache)) + return MethodInvalidations(methinvs.method, methinvs.reason, mt_backedges, backedges, copy(methinvs.mt_cache), copy(methinvs.mt_disable)) end function filtermod(mod::Module, node::InstanceNode) @@ -479,12 +491,12 @@ function findcaller(meth::Method, methinvs::MethodInvalidations) for (sig, node) in methinvs.mt_backedges ret = findcaller(meth, node) ret === nothing && continue - return MethodInvalidations(methinvs.method, methinvs.reason, [Pair{Any,InstanceNode}(sig, newtree(ret))], InstanceNode[], copy(methinvs.mt_cache)) + return MethodInvalidations(methinvs.method, methinvs.reason, [Pair{Any,InstanceNode}(sig, newtree(ret))], InstanceNode[], copy(methinvs.mt_cache), copy(methinvs.mt_disable)) end for node in methinvs.backedges ret = findcaller(meth, node) ret === nothing && continue - return MethodInvalidations(methinvs.method, methinvs.reason, Pair{Any,InstanceNode}[], [newtree(ret)], copy(methinvs.mt_cache)) + return MethodInvalidations(methinvs.method, methinvs.reason, Pair{Any,InstanceNode}[], [newtree(ret)], copy(methinvs.mt_cache), copy(methinvs.mt_disable)) end return nothing end diff --git a/test/colortypes.jl b/test/colortypes.jl index 1d59ea11..50ec1107 100644 --- a/test/colortypes.jl +++ b/test/colortypes.jl @@ -5,6 +5,7 @@ using SnoopCompile, Test, Pkg @test success @test modsym == :ColorTypes + @info "Beginning @snoopc test on ColorTypes. Note failures in ColorTypes' tests do not count as failures here." mktempdir() do tmpdir tmpfile = joinpath(tmpdir, "colortypes_compiles.csv") tmpdir2 = joinpath(tmpdir, "precompile") diff --git a/test/snoopr.jl b/test/snoopr.jl index 969717d0..87794949 100644 --- a/test/snoopr.jl +++ b/test/snoopr.jl @@ -180,6 +180,22 @@ end @test tree.reason === :deleting @test tree.method == m + # Method overwriting + invs = @snoopr begin + @eval Module() begin + Base.@irrational twoπ 6.2831853071795864769 2*big(π) + Base.@irrational twoπ 6.2831853071795864769 2*big(π) + end + end + trees = invalidation_trees(invs) + @test length(trees) == 3 + io = IOBuffer() + show(io, trees) + str = String(take!(io)) + @test occursin(r"deleting Float64\(::Irrational{:twoπ}\).*invalidated:\n.*mt_disable: MethodInstance for Float64\(::Irrational{:twoπ}\)", str) + @test occursin(r"deleting Float32\(::Irrational{:twoπ}\).*invalidated:\n.*mt_disable: MethodInstance for Float32\(::Irrational{:twoπ}\)", str) + @test occursin(r"deleting BigFloat\(::Irrational{:twoπ}; precision\).*invalidated:\n.*backedges: 1: .*with MethodInstance for BigFloat\(::Irrational{:twoπ}\) \(1 children\)", str) + # Exclusion of Core.Compiler methods invs = @snoopr (::Type{T})(x::SnooprTests.MyInt) where T<:Integer = T(x.x) umis1 = uinvalidated(invs)