|
1 | 1 | # MethodAnalysis.jl
|
2 | 2 |
|
3 |
| -```@index |
| 3 | +This package facilitates introspection of Julia's internals, with a particular focus on its MethodInstances and their backedges. |
| 4 | + |
| 5 | +!!! warning |
| 6 | + Julia's internals are not subject to the same stability guarantee that the rest of the language enjoys. |
| 7 | + |
| 8 | +## Demonstrations |
| 9 | + |
| 10 | +A few demonstrations will give you a taste of what can be done with this package. |
| 11 | + |
| 12 | +### Collecting all submodules of Base |
| 13 | + |
| 14 | +```jldoctest |
| 15 | +julia> using MethodAnalysis |
| 16 | +
|
| 17 | +julia> mods = Module[]; |
| 18 | +
|
| 19 | +julia> visit(Base; print=false) do obj |
| 20 | + if isa(obj, Module) |
| 21 | + push!(mods, obj) |
| 22 | + end |
| 23 | + end |
| 24 | +
|
| 25 | +julia> Base.FastMath ∈ mods |
| 26 | +true |
4 | 27 | ```
|
5 | 28 |
|
6 |
| -```@autodocs |
7 |
| -Modules = [MethodAnalysis] |
| 29 | +### Collecting all Methods in Core.Compiler |
| 30 | + |
| 31 | +`visit` also descends into functions, methods, and MethodInstances: |
| 32 | + |
| 33 | +```jldoctest; setup=:(using MethodAnalysis) |
| 34 | +julia> meths = [] |
| 35 | +Any[] |
| 36 | +
|
| 37 | +julia> visit(Core.Compiler) do item # without print=false it will display the modules it visits |
| 38 | + isa(item, Method) && push!(meths, item) |
| 39 | + end |
| 40 | +Module Core.Compiler |
| 41 | +Module Core.Compiler.CoreDocs |
| 42 | +Module Core.Compiler.Iterators |
| 43 | +Module Core.Compiler.Order |
| 44 | +Module Core.Compiler.Sort |
| 45 | +Module Core.Compiler.Sort.Float |
| 46 | +
|
| 47 | +julia> first(methods(Core.Compiler.typeinf_ext)) ∈ meths |
| 48 | +true |
| 49 | +``` |
| 50 | + |
| 51 | +### Getting a MethodInstance for a particular set of types |
| 52 | + |
| 53 | +```jldoctest; setup=:(using MethodAnalysis) |
| 54 | +julia> foo(::AbstractVector) = 1 |
| 55 | +foo (generic function with 1 method) |
| 56 | +
|
| 57 | +julia> instance(foo, (Vector{Int},)) # we haven't called it yet, so it's not compiled |
| 58 | +
|
| 59 | +julia> foo([1,2]) |
| 60 | +1 |
| 61 | +
|
| 62 | +julia> instance(foo, (Vector{Int},)) |
| 63 | +MethodInstance for foo(::Array{Int64,1}) |
| 64 | +``` |
| 65 | + |
| 66 | +### Collecting a subset of MethodInstances for a particular function |
| 67 | + |
| 68 | +Let's collect all single-argument compiled instances of `findfirst`: |
| 69 | + |
| 70 | +```jldoctest findfirst; setup=:(using MethodAnalysis) |
| 71 | +julia> mis = Core.MethodInstance[]; |
| 72 | +
|
| 73 | +julia> visit(findfirst) do item |
| 74 | + isa(item, Core.MethodInstance) && length(Base.unwrap_unionall(item.specTypes).parameters) == 2 && push!(mis, item) |
| 75 | + end |
| 76 | +
|
| 77 | +julia> mis |
| 78 | +1-element Array{Core.MethodInstance,1}: |
| 79 | + MethodInstance for findfirst(::BitArray{1}) |
| 80 | +``` |
| 81 | + |
| 82 | +We checked that the length was 2, rather than 1, because the first parameter is the function type itself: |
| 83 | + |
| 84 | +```jldoctest findfirst |
| 85 | +julia> mis[1].specTypes |
| 86 | +Tuple{typeof(findfirst),BitArray{1}} |
| 87 | +``` |
| 88 | + |
| 89 | +## Getting the backedges for a function |
| 90 | + |
| 91 | +Let's see all the compiled instances of `Base.setdiff` and their immediate callers: |
| 92 | + |
| 93 | +```jldoctest; setup=(using MethodAnalysis) |
| 94 | +julia> direct_backedges(setdiff) |
| 95 | +3-element Array{Any,1}: |
| 96 | + MethodInstance for setdiff(::Base.KeySet{Any,Dict{Any,Any}}, ::Base.KeySet{Any,Dict{Any,Any}}) => MethodInstance for keymap_merge(::Dict{Char,Any}, ::Dict{Any,Any}) |
| 97 | + MethodInstance for setdiff(::Base.KeySet{Any,Dict{Any,Any}}, ::Base.KeySet{Any,Dict{Any,Any}}) => MethodInstance for keymap_merge(::Any, ::Dict{Any,Any}) |
| 98 | + MethodInstance for setdiff(::Array{Base.UUID,1}, ::Array{Base.UUID,1}) => MethodInstance for deps_graph(::Pkg.Types.Context, ::Dict{Base.UUID,String}, ::Dict{Base.UUID,Pkg.Types.VersionSpec}, ::Dict{Base.UUID,Pkg.Resolve.Fixed}) |
| 99 | +``` |
| 100 | + |
| 101 | +## API reference |
| 102 | + |
| 103 | +### visit |
| 104 | + |
| 105 | +```@docs |
| 106 | +visit |
| 107 | +visit_backedges |
| 108 | +``` |
| 109 | + |
| 110 | +### backedges |
| 111 | + |
| 112 | +```@docs |
| 113 | +all_backedges |
| 114 | +direct_backedges |
| 115 | +terminal_backedges |
| 116 | +with_all_backedges |
| 117 | +``` |
| 118 | + |
| 119 | +### utilities |
| 120 | + |
| 121 | +```@docs |
| 122 | +instance |
| 123 | +call_type |
| 124 | +worlds |
8 | 125 | ```
|
0 commit comments