Created
April 8, 2026 14:04
-
-
Save KristofferC/fc196920213d35d0ecdc4ecbe9ab1a72 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using SnoopCompileCore | |
| # First load OhMyREPL so its methods are compiled | |
| using OhMyREPL | |
| # Now track invalidations caused by loading SymbolicUtils | |
| invs = @snoop_invalidations using SymbolicUtils; | |
| using SnoopCompile | |
| using SnoopCompile: countchildren | |
| trees = invalidation_trees(invs) | |
| # ── helpers ────────────────────────────────────────────────────────── | |
| function find_matching_nodes(node::SnoopCompile.InstanceNode, pred, | |
| path=SnoopCompile.InstanceNode[]) | |
| results = [] | |
| if pred(node) | |
| push!(results, (node=node, path=copy(path))) | |
| end | |
| push!(path, node) | |
| for child in node.children | |
| append!(results, find_matching_nodes(child, pred, path)) | |
| end | |
| pop!(path) | |
| return results | |
| end | |
| function search_trees(trees, pred) | |
| results = [] | |
| for tree in trees | |
| for node in tree.backedges | |
| for r in find_matching_nodes(node, pred) | |
| push!(results, (tree=tree, r...)) | |
| end | |
| end | |
| for (sig, node) in tree.mt_backedges | |
| for r in find_matching_nodes(node, pred) | |
| push!(results, (tree=tree, sig=sig, r...)) | |
| end | |
| end | |
| end | |
| return results | |
| end | |
| function print_results(results; verbose=false) | |
| println("Found $(length(results)) matches\n") | |
| for (i, r) in enumerate(results) | |
| println("--- Match $i ---") | |
| println(" Invalidated: ", r.node.mi) | |
| println(" Trigger: ", r.tree.method) | |
| println(" Reason: ", r.tree.reason) | |
| if hasproperty(r, :sig) | |
| println(" Via sig: ", r.sig) | |
| end | |
| if verbose | |
| println(" Path ($(length(r.path)) hops):") | |
| for (j, p) in enumerate(r.path) | |
| println(" $j: ", p.mi) | |
| end | |
| end | |
| println() | |
| end | |
| end | |
| """ | |
| find_invalidations(pattern; verbose=false) | |
| Search all invalidation trees for MethodInstances matching `pattern`. | |
| `pattern` can be a string (matched with `occursin`) or a regex. | |
| """ | |
| function find_invalidations(pattern::Union{AbstractString, Regex}; verbose=false) | |
| pred = if pattern isa Regex | |
| node -> occursin(pattern, string(node.mi)) | |
| else | |
| node -> occursin(pattern, string(node.mi)) | |
| end | |
| results = search_trees(trees, pred) | |
| print_results(results; verbose) | |
| return results | |
| end | |
| # ── run ────────────────────────────────────────────────────────────── | |
| if !isempty(ARGS) | |
| find_invalidations(ARGS[1]; verbose="--verbose" in ARGS || "-v" in ARGS) | |
| else | |
| println(""" | |
| Usage (from CLI): | |
| julia --project find_invalidation.jl <pattern> [-v] | |
| Examples: | |
| julia --project find_invalidation.jl OhMyREPL -v | |
| julia --project find_invalidation.jl create_keybindings | |
| julia --project find_invalidation.jl LineEdit | |
| Or interactively after `include("find_invalidation.jl")`: | |
| find_invalidations("OhMyREPL"; verbose=true) | |
| find_invalidations(r"keymap|keybinding"i) | |
| """) | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment