Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

snoopr ("snoop recompilations") to detect method invalidations #79

Merged
merged 2 commits into from
Jun 9, 2020

Conversation

timholy
Copy link
Owner

@timholy timholy commented May 8, 2020

Also provide infrastructure analyze and explain these invalidations.

This is WIP and could break any time. But here's a demo (must be run on JuliaLang/julia#35768):

julia> using SnoopCompile

julia> invalidations = @snoopr using FixedPointNumbers
1159-element Array{Any,1}:
   MethodInstance for reduce_empty(::Base.BottomRF{typeof(max)}, ::Type{VersionNumber})
  1
   MethodInstance for reduce_empty_iter(::Base.BottomRF{typeof(max)}, ::Set{VersionNumber}, ::Base.HasEltype)
  2
   MethodInstance for reduce_empty_iter(::Base.BottomRF{typeof(max)}, ::Set{VersionNumber})
  3
   MethodInstance for foldl_impl(::Base.BottomRF{typeof(max)}, ::NamedTuple{(),Tuple{}}, ::Set{VersionNumber})
  4
   MethodInstance for mapfoldl_impl(::typeof(identity), ::typeof(max), ::NamedTuple{(),Tuple{}}, ::Set{VersionNumber})
  5
   MethodInstance for #mapfoldl#201(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(mapfoldl), ::typeof(identity), ::typeof(max), ::Set{VersionNumber})
  6
   MethodInstance for mapfoldl(::typeof(identity), ::typeof(max), ::Set{VersionNumber})
  7
   MethodInstance for #mapreduce#205(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(mapreduce), ::typeof(identity), ::typeof(max), ::Set{VersionNumber})
  8
   MethodInstance for mapreduce(::typeof(identity), ::typeof(max), ::Set{VersionNumber})
  9
   MethodInstance for maximum(::Set{VersionNumber})
 10
   MethodInstance for set_maximum_version_registry!(::Pkg.Types.Context, ::Pkg.Types.PackageSpec)
 11
   MethodInstance for collect_project!(::Pkg.Types.Context, ::Pkg.Types.PackageSpec, ::String, ::Dict{Base.UUID,Array{Pkg.Types.PackageSpec,1}})
 12
  
 24
   MethodInstance for #ensure_artifact_installed#42(::Pkg.BinaryPlatforms.Linux, ::Bool, ::Bool, ::typeof(Pkg.Artifacts.ensure_artifact_installed), ::String, ::Dict, ::String)
 24
   MethodInstance for #ensure_artifact_installed#42(::Pkg.BinaryPlatforms.Platform, ::Bool, ::Bool, ::typeof(Pkg.Artifacts.ensure_artifact_installed), ::String, ::Dict{String,Any}, ::String)
 24
   MethodInstance for #ensure_artifact_installed#42(::Pkg.BinaryPlatforms.Linux, ::Bool, ::Bool, ::typeof(Pkg.Artifacts.ensure_artifact_installed), ::String, ::Dict{String,Any}, ::String)
 24
   MethodInstance for (::Pkg.Artifacts.var"#download_artifact##kw")(::NamedTuple{(:verbose, :quiet_download),Tuple{Bool,Bool}}, ::typeof(Pkg.Artifacts.download_artifact), ::Base.SHA1, ::String, ::Union{Nothing, String})
 20
   MethodInstance for #download_verify#93(::Bool, ::Bool, ::Bool, ::typeof(Pkg.PlatformEngines.download_verify), ::String, ::String, ::String)
 13
   MethodInstance for install_archive(::Array{Pair{String,Bool},1}, ::Base.SHA1, ::String)
 13
   MethodInstance for (::Pkg.Operations.var"#54#57"{Bool,Pkg.Types.Context,Dict{Base.UUID,Array{String,1}},Channel{Any},Channel{Any}})()
 14
   MethodInstance for _searchindex(::AbstractString, ::AbstractChar, ::Int64)
  5
   MethodInstance for (::Type{T} where T<:AbstractChar)(::Int32)
  1
   MethodInstance for lowercase(::T) where T<:AbstractChar
  1
   MethodInstance for uppercase(::T) where T<:AbstractChar
  1
   (::Type{X})(x::Real) where X<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:51

julia> trees = invalidation_trees(invalidations)
5-element Array{Pair{Union{Method, Core.MethodInstance},SnoopCompile.Invalidations},1}:
                                   Defining one(::Type{X}) where X<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:94 invalidated:

instances: signature Tuple{typeof(one),Type{T} where T<:AbstractChar} triggered MethodInstance for oneunit(::Type{T} where T<:AbstractChar) (1 children)
tables: MethodInstance for zero(::Type{Int32}) (0 children)
        MethodInstance for <=(::Int32, ::Int64) (0 children)
        MethodInstance for reinterpret(::Type{Char}, ::UInt32) (0 children)
        MethodInstance for max(::Int32, ::Int32) (0 children)
        MethodInstance for +(::Float64, ::Int64) (0 children)
        MethodInstance for one(::Type{UInt64}) (0 children)

       Defining promote_rule(::Type{T}, ::Type{Tf}) where {T<:Normed, Tf<:AbstractFloat} in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/normed.jl:310 invalidated:

tables: MethodInstance for ==(::Int64, ::Int64) (0 children)
        MethodInstance for ==(::Int32, ::Int64) (0 children)
        MethodInstance for ==(::Int32, ::Int32) (2 children)

                               Defining sizeof(::Type{X}) where X<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:100 invalidated:

tables: MethodInstance for min(::Int64, ::Int64) (0 children)
        MethodInstance for min(::Int32, ::Int32) (0 children)
        MethodInstance for /(::UInt64, ::Float64) (0 children)
        MethodInstance for *(::Float64, ::Int64) (0 children)
        MethodInstance for *(::UInt64, ::Float64) (0 children)
        MethodInstance for oneunit(::Int32) (0 children)
        MethodInstance for sizeof(::Type{T} where T) (31 children)

 Defining reduce_empty(::typeof(Base.add_sum), ::Type{F}) where F<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:222 invalidated:

instances: MethodInstance for reduce_empty(::Base.BottomRF{typeof(max)}, ::Type{VersionNumber}) (136 children)

                             Defining (::Type{X})(x::Real) where X<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:51 invalidated:

instances: signature Tuple{Type{T} where T<:Int64,Int64} triggered MethodInstance for convert(::Type{T}, ::Int64) where T<:Int64 (386 children)
tables: MethodInstance for Char(::Int64) (0 children)


julia> explain(trees[end])
New method: (::Type{X})(x::Real) where X<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:51
Invalidated:
  signature Tuple{Type{T} where T<:Int64,Int64}:
    intersection: Tuple{Type{Union{}},Int64}
    matching method Int64(x::Union{Bool, Int32, Int64, UInt32, UInt64, UInt8, Int128, Int16, Int8, UInt128, UInt16}) in Core at boot.jl:707
    matching method (::Type{T})(x::T) where T<:Number in Core at boot.jl:715
  386 direct and indirect descendants
  method table for MethodInstance for Char(::Int64)
    0 direct and indirect descendants

julia> explain(trees[end-1])
New method: reduce_empty(::typeof(Base.add_sum), ::Type{F}) where F<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:222
Invalidated:
    MethodInstance for reduce_empty(::Base.BottomRF{typeof(max)}, ::Type{VersionNumber})
  136 direct and indirect descendants

julia> explain(trees[end-2])
New method: sizeof(::Type{X}) where X<:FixedPoint in FixedPointNumbers at /home/tim/.julia/packages/FixedPointNumbers/w2pxG/src/FixedPointNumbers.jl:100
Invalidated:
  method table for MethodInstance for min(::Int64, ::Int64)
    0 direct and indirect descendants
  method table for MethodInstance for min(::Int32, ::Int32)
    0 direct and indirect descendants
  method table for MethodInstance for /(::UInt64, ::Float64)
    0 direct and indirect descendants
  method table for MethodInstance for *(::Float64, ::Int64)
    0 direct and indirect descendants
  method table for MethodInstance for *(::UInt64, ::Float64)
    0 direct and indirect descendants
  method table for MethodInstance for oneunit(::Int32)
    0 direct and indirect descendants
  method table for MethodInstance for sizeof(::Type{T} where T)
    31 direct and indirect descendants

# This doesn't technically have to be mutable but it's more convenient for testing equality
mutable struct InstanceTree
mi::MethodInstance
depth::Int32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to use Int32 here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly necessary but that's the type that gets loaded into the returned array (in C, int == Int32).

@timholy timholy force-pushed the teh/invalidations branch from 0f3ecf0 to ff8f48f Compare May 11, 2020 12:57
@timholy timholy force-pushed the teh/invalidations branch 2 times, most recently from 5bca0d3 to b45849c Compare June 9, 2020 12:42
@timholy timholy force-pushed the teh/invalidations branch from b45849c to 99fb305 Compare June 9, 2020 12:54
Also provide infrastructure analyze and explain these invalidations.
This organizes the call chain as a tree and adds analysis and
printing to facilitate understand of the most consequential invalidations.
@timholy timholy force-pushed the teh/invalidations branch from 99fb305 to 1bb85ec Compare June 9, 2020 13:22
@timholy
Copy link
Owner Author

timholy commented Jun 9, 2020

OK, let's do this!

@timholy timholy merged commit f624b45 into master Jun 9, 2020
@timholy timholy deleted the teh/invalidations branch June 9, 2020 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants