From b9f8b8b864717bf766ef08da57642fc42a30fb30 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 29 Jan 2021 02:33:07 -0500 Subject: [PATCH] remove bad method specialization from cache (#39429) This was inserting a method with signature [Int, Int], rather than Tuple{typeof(+), Int, Int}. Fix that and add a test for it so it doesn't happen again. --- base/Base.jl | 61 ++++++++++++++++++++++++++-------------------------- src/gf.c | 4 +++- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 878448c3e3964..d1a549f897d4f 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -394,37 +394,36 @@ in_sysimage(pkgid::PkgId) = pkgid in _sysimage_modules # Precompiles for Revise # TODO: move these to contrib/generate_precompile.jl # The problem is they don't work there -let m = which(+, (Int, Int)) - while true # defeat interpreter heuristic to force compilation - delete!(push!(Set{Method}(), m), m) - copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(m, [Int, Int], Core.svec()))) - - empty!(Set()) - push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two)) - (setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"] - (setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two] - (setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)] - (setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two] - (setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int] - Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one] - Dict(Base => [:(1+1)])[Base] - Dict(:one => [1])[:one] - Dict("abc" => Set())["abc"] - pushfirst!([], sum) - get(Base.pkgorigins, Base.PkgId(Base), nothing) - sort!([1,2,3]) - unique!([1,2,3]) - cumsum([1,2,3]) - append!(Int[], BitSet()) - isempty(BitSet()) - delete!(BitSet([1,2]), 3) - deleteat!(Int32[1,2,3], [1,3]) - deleteat!(Any[1,2,3], [1,3]) - Core.svec(1, 2) == Core.svec(3, 4) - any(t->t[1].line > 1, [(LineNumberNode(2,:none), :(1+1))]) - - break # end defeat interpreter heuristic - end +for match = _methods(+, (Int, Int), -1, get_world_counter()) + m = match.method + delete!(push!(Set{Method}(), m), m) + copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(match))) + + empty!(Set()) + push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two)) + (setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"] + (setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two] + (setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)] + (setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two] + (setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int] + Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one] + Dict(Base => [:(1+1)])[Base] + Dict(:one => [1])[:one] + Dict("abc" => Set())["abc"] + pushfirst!([], sum) + get(Base.pkgorigins, Base.PkgId(Base), nothing) + sort!([1,2,3]) + unique!([1,2,3]) + cumsum([1,2,3]) + append!(Int[], BitSet()) + isempty(BitSet()) + delete!(BitSet([1,2]), 3) + deleteat!(Int32[1,2,3], [1,3]) + deleteat!(Any[1,2,3], [1,3]) + Core.svec(1, 2) == Core.svec(3, 4) + any(t->t[1].line > 1, [(LineNumberNode(2,:none), :(1+1))]) + + break # only actually need to do this once end if is_primary_base_module diff --git a/src/gf.c b/src/gf.c index 63a9a6dbc0494..27a7d85e5a4c4 100644 --- a/src/gf.c +++ b/src/gf.c @@ -104,7 +104,9 @@ static int speccache_eq(size_t idx, const void *ty, jl_svec_t *data, uint_t hv) // get or create the MethodInstance for a specialization JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams) { - uint_t hv = ((jl_datatype_t*)(jl_is_unionall(type) ? jl_unwrap_unionall(type) : type))->hash; + jl_value_t *ut = jl_is_unionall(type) ? jl_unwrap_unionall(type) : type; + JL_TYPECHK(specializations, datatype, ut); + uint_t hv = ((jl_datatype_t*)ut)->hash; for (int locked = 0; ; locked++) { jl_array_t *speckeyset = jl_atomic_load_acquire(&m->speckeyset); jl_svec_t *specializations = jl_atomic_load_acquire(&m->specializations);