From b07fb407104ef8338c129296019cfe55c7c43f64 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 28 Feb 2023 20:09:15 -0500 Subject: [PATCH] gf: cache cache_with_orig decision (#48833) Memoizing this can save a lot of repeated effort for queries such as `@which eltype(String)`. Otherwise we repeatedly try to check if `eltype(::Type)` is a good way to cache that result, even though it never gets better the more we check it. (cherry picked from commit bdcd5e2c6d0fdea879a961f1a72d774b743cc846) --- src/gf.c | 6 ++++++ src/jltypes.c | 6 ++++-- src/julia.h | 1 + src/method.c | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gf.c b/src/gf.c index d7acac2526fff..443cebcf58e71 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1195,6 +1195,8 @@ static jl_method_instance_t *cache_method( } // TODO: maybe assert(jl_isa_compileable_sig(compilationsig, sparams, definition)); newmeth = jl_specializations_get_linfo(definition, (jl_value_t*)compilationsig, sparams); + if (newmeth->cache_with_orig) + cache_with_orig = 1; jl_tupletype_t *cachett = tt; jl_svec_t* guardsigs = jl_emptysvec; @@ -1261,6 +1263,10 @@ static jl_method_instance_t *cache_method( max_valid = max_valid2; cachett = compilationsig; } + else { + // do not revisit this decision + newmeth->cache_with_orig = 1; + } } // now scan `cachett` and ensure that `Type{T}` in the cache will be matched exactly by `typeof(T)` diff --git a/src/jltypes.c b/src/jltypes.c index 4ede9467be043..116efa705558f 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2531,7 +2531,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_method_instance_type = jl_new_datatype(jl_symbol("MethodInstance"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(9, + jl_perm_symsvec(10, "def", "specTypes", "sparam_vals", @@ -2540,8 +2540,9 @@ void jl_init_types(void) JL_GC_DISABLED "callbacks", "cache", "inInference", + "cache_with_orig", "precompiled"), - jl_svec(9, + jl_svec(10, jl_new_struct(jl_uniontype_type, jl_method_type, jl_module_type), jl_any_type, jl_simplevector_type, @@ -2550,6 +2551,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type, jl_any_type, jl_bool_type, + jl_bool_type, jl_bool_type), jl_emptysvec, 0, 1, 3); diff --git a/src/julia.h b/src/julia.h index d5697f75297d0..f75d240d92595 100644 --- a/src/julia.h +++ b/src/julia.h @@ -369,6 +369,7 @@ struct _jl_method_instance_t { jl_array_t *callbacks; // list of callback functions to inform external caches about invalidations _Atomic(struct _jl_code_instance_t*) cache; uint8_t inInference; // flags to tell if inference is running on this object + uint8_t cache_with_orig; // !cache_with_specTypes uint8_t precompiled; // true if this instance was generated by an explicit `precompile(...)` call }; diff --git a/src/method.c b/src/method.c index 852c5bf25659a..f6da5106433d1 100644 --- a/src/method.c +++ b/src/method.c @@ -447,6 +447,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_new_method_instance_uninit(void) li->callbacks = NULL; jl_atomic_store_relaxed(&li->cache, NULL); li->inInference = 0; + li->inInference = 0; li->precompiled = 0; return li; }