LCOV - code coverage report
Current view: top level - src - typemap.c (source / functions) Hit Total Coverage
Test: [build process] commit ef510b1f346f4c9f9d86eaceace5ca54961a1dbc Lines: 699 779 89.7 %
Date: 2022-07-17 01:01:28 Functions: 31 33 93.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 626 764 81.9 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : #include <stdlib.h>
       4                 :            : #include <string.h>
       5                 :            : #include "julia.h"
       6                 :            : #include "julia_internal.h"
       7                 :            : #ifndef _OS_WINDOWS_
       8                 :            : #include <unistd.h>
       9                 :            : #endif
      10                 :            : #include "julia_assert.h"
      11                 :            : 
      12                 :            : #define MAX_METHLIST_COUNT 12 // this can strongly affect the sysimg size and speed!
      13                 :            : 
      14                 :            : #ifdef __cplusplus
      15                 :            : extern "C" {
      16                 :            : #endif
      17                 :            : 
      18                 :            : // compute whether the specificity of this type is equivalent to Any in the sort order
      19                 :      98554 : static int jl_is_any(jl_value_t *t1)
      20                 :            : {
      21         [ +  + ]:      99128 :     while (jl_is_typevar(t1))
      22                 :        574 :         t1 = ((jl_tvar_t*)t1)->ub;
      23                 :      98554 :     return t1 == (jl_value_t*)jl_any_type;
      24                 :            : }
      25                 :            : 
      26                 :    5103700 : static jl_value_t *jl_type_extract_name(jl_value_t *t1 JL_PROPAGATES_ROOT)
      27                 :            : {
      28         [ +  + ]:    5103700 :     if (jl_is_unionall(t1))
      29                 :    1875260 :         t1 = jl_unwrap_unionall(t1);
      30         [ -  + ]:    5103700 :     if (jl_is_vararg(t1)) {
      31                 :          0 :         return jl_type_extract_name(jl_unwrap_vararg(t1));
      32                 :            :     }
      33         [ +  + ]:    5103700 :     else if (jl_is_typevar(t1)) {
      34                 :      10000 :         return jl_type_extract_name(((jl_tvar_t*)t1)->ub);
      35                 :            :     }
      36         [ +  + ]:    5093700 :     else if (jl_is_datatype(t1)) {
      37                 :    4368950 :         jl_datatype_t *dt = (jl_datatype_t*)t1;
      38         [ +  + ]:    4368950 :         if (!jl_is_kind(t1))
      39                 :    4362990 :             return (jl_value_t*)dt->name;
      40                 :       5958 :         return NULL;
      41                 :            :     }
      42         [ +  + ]:     724747 :     else if (jl_is_uniontype(t1)) {
      43                 :     724584 :         jl_uniontype_t *u1 = (jl_uniontype_t*)t1;
      44                 :     724584 :         jl_value_t *tn1 = jl_type_extract_name(u1->a);
      45                 :     724584 :         jl_value_t *tn2 = jl_type_extract_name(u1->b);
      46         [ +  + ]:     724584 :         if (tn1 == tn2)
      47                 :        869 :             return tn1;
      48                 :            :         // TODO: if invariant is false, instead find the nearest common ancestor
      49                 :     723715 :         return NULL;
      50                 :            :     }
      51                 :        163 :     return NULL;
      52                 :            : }
      53                 :            : 
      54                 :            : // return false if the name extracted above is an over-approximation
      55                 :            : // (such that intersection also needs to consider the subtypes)
      56                 :     254085 : static int jl_type_extract_name_precise(jl_value_t *t1, int invariant)
      57                 :            : {
      58         [ +  + ]:     254085 :     if (jl_is_unionall(t1))
      59                 :      45748 :         t1 = jl_unwrap_unionall(t1);
      60         [ -  + ]:     254085 :     if (jl_is_vararg(t1)) {
      61                 :          0 :         return jl_type_extract_name_precise(jl_unwrap_vararg(t1), invariant);
      62                 :            :     }
      63         [ -  + ]:     254085 :     else if (jl_is_typevar(t1)) {
      64                 :          0 :         return jl_type_extract_name_precise(((jl_tvar_t*)t1)->ub, 0);
      65                 :            :     }
      66         [ +  + ]:     254085 :     else if (jl_is_datatype(t1)) {
      67                 :     253931 :         jl_datatype_t *dt = (jl_datatype_t*)t1;
      68   [ +  +  +  +  :     253931 :         if ((invariant || !dt->name->abstract) && !jl_is_kind(t1))
                   +  - ]
      69                 :     184765 :             return 1;
      70                 :      69166 :         return 0;
      71                 :            :     }
      72         [ +  - ]:        154 :     else if (jl_is_uniontype(t1)) {
      73                 :        154 :         jl_uniontype_t *u1 = (jl_uniontype_t*)t1;
      74         [ +  + ]:        154 :         if (!jl_type_extract_name_precise(u1->a, invariant))
      75                 :         58 :             return 0;
      76         [ -  + ]:         96 :         if (!jl_type_extract_name_precise(u1->b, invariant))
      77                 :          0 :             return 0;
      78                 :         96 :         jl_value_t *tn1 = jl_type_extract_name(u1->a);
      79                 :         96 :         jl_value_t *tn2 = jl_type_extract_name(u1->b);
      80         [ +  - ]:         96 :         if (tn1 == tn2)
      81                 :         96 :             return 1;
      82                 :          0 :         return 0;
      83                 :            :     }
      84                 :          0 :     return 1;
      85                 :            : }
      86                 :            : 
      87                 :            : 
      88                 :            : // ----- Type Signature Subtype Testing ----- //
      89                 :            : 
      90                 :          0 : static int sig_match_by_type_leaf(jl_value_t **types, jl_tupletype_t *sig, size_t n)
      91                 :            : {
      92                 :            :     size_t i;
      93         [ #  # ]:          0 :     for (i = 0; i < n; i++) {
      94                 :          0 :         jl_value_t *decl = jl_tparam(sig, i);
      95                 :          0 :         jl_value_t *a = types[i];
      96         [ #  # ]:          0 :         if (jl_is_type_type(a)) // decl is not Type, because it wouldn't be leafsig
      97                 :          0 :             a = jl_typeof(jl_tparam0(a));
      98         [ #  # ]:          0 :         if (!jl_types_equal(a, decl))
      99                 :          0 :             return 0;
     100                 :            :     }
     101                 :          0 :     return 1;
     102                 :            : }
     103                 :            : 
     104                 :    1042400 : static int sig_match_by_type_simple(jl_value_t **types, size_t n, jl_tupletype_t *sig, size_t lensig, int va)
     105                 :            : {
     106                 :            :     size_t i;
     107         [ +  + ]:    1042400 :     if (va) lensig -= 1;
     108         [ +  + ]:    2899300 :     for (i = 0; i < lensig; i++) {
     109                 :    2432670 :         jl_value_t *decl = jl_tparam(sig, i);
     110                 :    2432670 :         jl_value_t *a = types[i];
     111         [ -  + ]:    2432670 :         jl_value_t *unw = jl_is_unionall(decl) ? ((jl_unionall_t*)decl)->body : decl;
     112         [ +  + ]:    2432670 :         if (jl_is_vararg(a))
     113                 :          1 :             return 0;
     114         [ +  + ]:    2432670 :         if (jl_is_type_type(unw)) {
     115                 :     208909 :             jl_value_t *tp0 = jl_tparam0(unw);
     116         [ +  - ]:     208909 :             if (jl_is_type_type(a)) {
     117         [ -  + ]:     208909 :                 if (jl_is_typevar(tp0)) {
     118                 :            :                     // in the case of Type{_}, the types don't have to match exactly.
     119                 :            :                     // this is cached as `Type{T} where T`.
     120   [ #  #  #  # ]:          0 :                     if (((jl_tvar_t*)tp0)->ub != (jl_value_t*)jl_any_type &&
     121                 :          0 :                         !jl_subtype(jl_tparam0(a), ((jl_tvar_t*)tp0)->ub))
     122                 :          0 :                         return 0;
     123                 :            :                 }
     124         [ +  + ]:     208909 :                 else if (!jl_types_equal(jl_tparam0(a), tp0)) {
     125                 :     142652 :                     return 0;
     126                 :            :                 }
     127                 :            :             }
     128   [ #  #  #  #  :          0 :             else if (!jl_is_kind(a) || !jl_is_typevar(tp0) || ((jl_tvar_t*)tp0)->ub != (jl_value_t*)jl_any_type) {
                   #  # ]
     129                 :            :                 // manually unroll jl_subtype(a, decl)
     130                 :            :                 // where `a` can be a subtype and decl is Type{T}
     131                 :          0 :                 return 0;
     132                 :            :             }
     133                 :            :         }
     134         [ +  + ]:    2223760 :         else if (decl == (jl_value_t*)jl_any_type) {
     135                 :            :         }
     136                 :            :         else {
     137         [ +  + ]:    1876390 :             if (jl_is_type_type(a)) // decl is not Type, because it would be caught above
     138                 :     472407 :                 a = jl_typeof(jl_tparam0(a));
     139         [ +  + ]:    1876390 :             if (!jl_types_equal(a, decl))
     140                 :     433118 :                 return 0;
     141                 :            :         }
     142                 :            :     }
     143         [ +  + ]:     466632 :     if (va) {
     144                 :      15798 :         jl_value_t *decl = jl_unwrap_unionall(jl_tparam(sig, i));
     145         [ -  + ]:      15798 :         if (jl_vararg_kind(decl) == JL_VARARG_INT) {
     146         [ #  # ]:          0 :             if (n - i != jl_unbox_long(jl_tparam1(decl)))
     147                 :          0 :                 return 0;
     148                 :            :         }
     149                 :      15798 :         jl_value_t *t = jl_unwrap_vararg(decl);
     150         [ -  + ]:      15798 :         if (jl_is_typevar(t))
     151                 :          0 :             t = ((jl_tvar_t*)t)->ub;
     152         [ +  + ]:      63991 :         for (; i < n; i++) {
     153                 :      49623 :             jl_value_t *ti = types[i];
     154   [ +  +  +  + ]:      49623 :             if (i == n - 1 && jl_is_vararg(ti))
     155                 :        152 :                 ti = jl_unwrap_vararg(ti);
     156         [ +  + ]:      49623 :             if (!jl_subtype(ti, t))
     157                 :       1430 :                 return 0;
     158                 :            :         }
     159                 :      14368 :         return 1;
     160                 :            :     }
     161                 :     450834 :     return 1;
     162                 :            : }
     163                 :            : 
     164                 :          0 : static inline int sig_match_leaf(jl_value_t *arg1, jl_value_t **args, jl_value_t **sig, size_t n)
     165                 :            : {
     166                 :            :     // NOTE: This function is a huge performance hot spot!!
     167                 :            :     size_t i;
     168         [ #  # ]:          0 :     if (jl_typeof(arg1) != sig[0])
     169                 :          0 :         return 0;
     170         [ #  # ]:          0 :     for (i = 1; i < n; i++) {
     171                 :          0 :         jl_value_t *decl = sig[i];
     172                 :          0 :         jl_value_t *a = args[i - 1];
     173         [ #  # ]:          0 :         if (jl_typeof(a) != decl) {
     174                 :            :             /*
     175                 :            :               we are only matching concrete types here, and those types are
     176                 :            :               hash-consed, so pointer comparison should work.
     177                 :            :             */
     178                 :          0 :             return 0;
     179                 :            :         }
     180                 :            :     }
     181                 :          0 :     return 1;
     182                 :            : }
     183                 :            : 
     184                 :  229371000 : static inline int sig_match_simple(jl_value_t *arg1, jl_value_t **args, size_t n, jl_value_t **sig,
     185                 :            :                                    int va, size_t lensig)
     186                 :            : {
     187                 :            :     // NOTE: This function is a performance hot spot!!
     188                 :            :     size_t i;
     189         [ +  + ]:  229371000 :     if (va)
     190                 :   49826700 :         lensig -= 1;
     191         [ +  + ]:  658183000 :     for (i = 0; i < lensig; i++) {
     192                 :  497060000 :         jl_value_t *decl = sig[i];
     193         [ +  + ]:  497060000 :         jl_value_t *a = (i == 0 ? arg1 : args[i - 1]);
     194   [ +  +  +  + ]:  497060000 :         if (jl_typeof(a) == decl || decl == (jl_value_t*)jl_any_type) {
     195                 :            :             /*
     196                 :            :               we are only matching concrete types here, and those types are
     197                 :            :               hash-consed, so pointer comparison should work.
     198                 :            :             */
     199                 :  422071000 :             continue;
     200                 :            :         }
     201         [ -  + ]:   74988600 :         jl_value_t *unw = jl_is_unionall(decl) ? ((jl_unionall_t*)decl)->body : decl;
     202   [ +  +  +  - ]:   81729500 :         if (jl_is_type_type(unw) && jl_is_type(a)) {
     203                 :   12193000 :             jl_value_t *tp0 = jl_tparam0(unw);
     204         [ -  + ]:   12193000 :             if (jl_is_typevar(tp0)) {
     205                 :            :                 // in the case of Type{_}, the types don't have to match exactly.
     206                 :            :                 // this is cached as `Type{T} where T`.
     207   [ #  #  #  # ]:          0 :                 if (((jl_tvar_t*)tp0)->ub != (jl_value_t*)jl_any_type &&
     208                 :          0 :                     !jl_subtype(a, ((jl_tvar_t*)tp0)->ub))
     209                 :          0 :                     return 0;
     210                 :            :             }
     211                 :            :             else {
     212         [ +  + ]:   12193000 :                 if (a != tp0) {
     213                 :    6023850 :                     jl_datatype_t *da = (jl_datatype_t*)a;
     214                 :    6023850 :                     jl_datatype_t *dt = (jl_datatype_t*)tp0;
     215         [ +  + ]:    6286370 :                     while (jl_is_unionall(da))
     216                 :     262519 :                         da = (jl_datatype_t*)((jl_unionall_t*)da)->body;
     217         [ +  + ]:    6286370 :                     while (jl_is_unionall(dt))
     218                 :     262519 :                         dt = (jl_datatype_t*)((jl_unionall_t*)dt)->body;
     219   [ +  +  +  -  :    6023850 :                     if (jl_is_datatype(da) && jl_is_datatype(dt) && da->name != dt->name)
                   +  + ]
     220                 :    3219350 :                         return 0;
     221         [ +  + ]:    2804500 :                     if (!jl_types_equal(a, tp0))
     222                 :    2232710 :                         return 0;
     223                 :            :                 }
     224                 :            :             }
     225                 :            :         }
     226                 :            :         else {
     227                 :   62795600 :             return 0;
     228                 :            :         }
     229                 :            :     }
     230         [ +  + ]:  161123000 :     if (va) {
     231                 :   49636300 :         jl_value_t *decl = sig[i];
     232         [ -  + ]:   49636300 :         if (jl_vararg_kind(decl) == JL_VARARG_INT) {
     233         [ #  # ]:          0 :             if (n - i != jl_unbox_long(jl_tparam1(decl)))
     234                 :          0 :                 return 0;
     235                 :            :         }
     236                 :   49636300 :         jl_value_t *t = jl_unwrap_vararg(decl);
     237         [ +  + ]:  195417000 :         for (; i < n; i++) {
     238         [ +  + ]:  145781000 :             jl_value_t *a = (i == 0 ? arg1 : args[i - 1]);
     239         [ +  + ]:  145781000 :             if (!jl_isa(a, t))
     240                 :         56 :                 return 0;
     241                 :            :         }
     242                 :   49636300 :         return 1;
     243                 :            :     }
     244                 :  111487000 :     return 1;
     245                 :            : }
     246                 :            : 
     247                 :            : 
     248                 :            : // ----- MethodCache helper functions ----- //
     249                 :            : 
     250                 :            : // predicate to fast-test if this type is a leaf type that can exist in the cache
     251                 :            : // and does not need a more expensive linear scan to find all intersections
     252                 :            : // be careful not to put non-leaf types or DataType/UnionAll/Union in the
     253                 :            : // argument cache, since they should have a lower priority and so will go in some
     254                 :            : // later list
     255                 :   12322400 : static int is_cache_leaf(jl_value_t *ty, int tparam)
     256                 :            : {
     257         [ +  + ]:   12322400 :     if (ty == jl_bottom_type)
     258                 :        504 :         return 1;
     259   [ +  +  +  +  :   12321900 :     return (jl_is_concrete_type(ty) && (tparam || !jl_is_kind(ty)));
                   +  + ]
     260                 :            : }
     261                 :            : 
     262                 :      66535 : static _Atomic(jl_typemap_t*) *mtcache_hash_lookup_bp(jl_array_t *cache JL_PROPAGATES_ROOT, jl_value_t *ty) JL_NOTSAFEPOINT
     263                 :            : {
     264         [ +  + ]:      66535 :     if (cache == (jl_array_t*)jl_an_empty_vec_any)
     265                 :       1888 :         return NULL;
     266                 :      64647 :     _Atomic(jl_typemap_t*) *pml = jl_table_peek_bp(cache, ty);
     267                 :            :     JL_GC_PROMISE_ROOTED(pml); // clang-sa doesn't trust our JL_PROPAGATES_ROOT claim
     268                 :      64647 :     return pml;
     269                 :            : }
     270                 :            : 
     271                 :      22613 : static void mtcache_hash_insert(_Atomic(jl_array_t*) *cache, jl_value_t *parent, jl_value_t *key, jl_typemap_t *val)
     272                 :            : {
     273                 :      22613 :     int inserted = 0;
     274                 :      22613 :     jl_array_t *a = jl_atomic_load_relaxed(cache);
     275         [ +  + ]:      22613 :     if (a == (jl_array_t*)jl_an_empty_vec_any) {
     276                 :       1888 :         a = jl_alloc_vec_any(16);
     277                 :       1888 :         jl_atomic_store_release(cache, a);
     278                 :       1888 :         jl_gc_wb(parent, a);
     279                 :            :     }
     280                 :      22613 :     a = jl_eqtable_put(a, key, val, &inserted);
     281         [ -  + ]:      22613 :     assert(inserted);
     282         [ +  + ]:      22613 :     if (a != jl_atomic_load_relaxed(cache)) {
     283                 :       1031 :         jl_atomic_store_release(cache, a);
     284                 :       1031 :         jl_gc_wb(parent, a);
     285                 :            :     }
     286                 :      22613 : }
     287                 :            : 
     288                 :   18069800 : static jl_typemap_t *mtcache_hash_lookup(jl_array_t *cache JL_PROPAGATES_ROOT, jl_value_t *ty) JL_NOTSAFEPOINT
     289                 :            : {
     290         [ -  + ]:   18069800 :     if (cache == (jl_array_t*)jl_an_empty_vec_any)
     291                 :          0 :         return (jl_typemap_t*)jl_nothing;
     292                 :   18069800 :     jl_typemap_t *ml = (jl_typemap_t*)jl_eqtable_get(cache, ty, jl_nothing);
     293                 :            :     JL_GC_PROMISE_ROOTED(ml); // clang-sa doesn't trust our JL_PROPAGATES_ROOT claim
     294                 :   18069800 :     return ml;
     295                 :            : }
     296                 :            : 
     297                 :            : // ----- Sorted Type Signature Lookup Matching ----- //
     298                 :            : 
     299                 :       8844 : static int jl_typemap_array_visitor(jl_array_t *a, jl_typemap_visitor_fptr fptr, void *closure)
     300                 :            : {
     301                 :       8844 :     size_t i, l = jl_array_len(a);
     302                 :       8844 :     _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_data(a);
     303         [ +  + ]:     207356 :     for (i = 1; i < l; i += 2) {
     304                 :     198512 :         jl_value_t *d = jl_atomic_load_relaxed(&data[i]);
     305                 :            :         JL_GC_PROMISE_ROOTED(d);
     306   [ +  +  -  + ]:     198512 :         if (d && !jl_typemap_visitor(d, fptr, closure))
     307                 :          0 :             return 0;
     308                 :            :     }
     309                 :       8844 :     return 1;
     310                 :            : }
     311                 :            : 
     312                 :            : 
     313                 :            : // calls fptr on each jl_typemap_entry_t in cache in sort order, until fptr return false
     314                 :     222596 : static int jl_typemap_node_visitor(jl_typemap_entry_t *ml, jl_typemap_visitor_fptr fptr, void *closure)
     315                 :            : {
     316         [ +  + ]:     618238 :     while (ml != (void*)jl_nothing) {
     317         [ +  + ]:     395648 :         if (!fptr(ml, closure))
     318                 :          6 :             return 0;
     319                 :     395642 :         ml = jl_atomic_load_relaxed(&ml->next);
     320                 :            :     }
     321                 :     222590 :     return 1;
     322                 :            : }
     323                 :            : 
     324                 :     222596 : int jl_typemap_visitor(jl_typemap_t *cache, jl_typemap_visitor_fptr fptr, void *closure)
     325                 :            : {
     326         [ +  + ]:     222596 :     if (jl_typeof(cache) == (jl_value_t*)jl_typemap_level_type) {
     327                 :       6012 :         jl_typemap_level_t *node = (jl_typemap_level_t*)cache;
     328                 :            :         jl_array_t *a;
     329                 :       6012 :         JL_GC_PUSH1(&a);
     330                 :       6012 :         a = jl_atomic_load_relaxed(&node->targ);
     331         [ +  + ]:       6012 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     332         [ -  + ]:        526 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     333                 :          0 :                 goto exit;
     334                 :       6012 :         a = jl_atomic_load_relaxed(&node->arg1);
     335         [ +  + ]:       6012 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     336         [ -  + ]:       4658 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     337                 :          0 :                 goto exit;
     338                 :       6012 :         a = jl_atomic_load_relaxed(&node->tname);
     339         [ +  + ]:       6012 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     340         [ -  + ]:        862 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     341                 :          0 :                 goto exit;
     342                 :       6012 :         a = jl_atomic_load_relaxed(&node->name1);
     343         [ +  + ]:       6012 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     344         [ -  + ]:       2798 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     345                 :          0 :                 goto exit;
     346         [ -  + ]:       6012 :         if (!jl_typemap_node_visitor(jl_atomic_load_relaxed(&node->linear), fptr, closure))
     347                 :          0 :             goto exit;
     348         [ -  + ]:       6012 :         if (!jl_typemap_visitor(jl_atomic_load_relaxed(&node->any), fptr, closure))
     349                 :          0 :             goto exit;
     350                 :       6012 :         JL_GC_POP();
     351                 :       6012 :         return 1;
     352                 :            :     }
     353                 :            :     else {
     354                 :     216584 :         return jl_typemap_node_visitor((jl_typemap_entry_t*)cache, fptr, closure);
     355                 :            :     }
     356                 :            : 
     357                 :          0 : exit:
     358                 :          0 :     JL_GC_POP();
     359                 :          0 :     return 0;
     360                 :            : }
     361                 :            : 
     362                 :      91516 : static unsigned jl_supertype_height(jl_datatype_t *dt)
     363                 :            : {
     364                 :      91516 :     unsigned height = 1;
     365         [ +  + ]:     156715 :     while (dt != jl_any_type) {
     366                 :      65199 :         height++;
     367                 :      65199 :         dt = dt->super;
     368                 :            :     }
     369                 :      91516 :     return height;
     370                 :            : }
     371                 :            : 
     372                 :            : // return true if a and b might intersect in the type domain (over just their type-names)
     373                 :     385021 : static int tname_intersection(jl_datatype_t *a, jl_typename_t *bname, unsigned ha)
     374                 :            : {
     375                 :     385021 :     jl_datatype_t *b = (jl_datatype_t*)jl_unwrap_unionall(bname->wrapper);
     376                 :     385021 :     unsigned hb = 1;
     377         [ +  + ]:     991358 :     while (b != jl_any_type) {
     378         [ +  + ]:     742580 :         if (a->name == b->name)
     379                 :     136243 :             return 1;
     380                 :     606337 :         hb++;
     381                 :     606337 :         b = b->super;
     382                 :            :     }
     383         [ +  + ]:     277677 :     while (ha > hb) {
     384                 :      28899 :         a = a->super;
     385                 :      28899 :         ha--;
     386                 :            :     }
     387                 :     248778 :     return a->name == bname;
     388                 :            : }
     389                 :            : 
     390                 :            : // tparam bit 1 is ::Type{T} (vs. T)
     391                 :            : // tparam bit 2 is typename(T) (vs. T)
     392                 :     179978 : static int jl_typemap_intersection_array_visitor(jl_array_t *a, jl_value_t *ty, int tparam,
     393                 :            :                                                  int offs, struct typemap_intersection_env *closure)
     394                 :            : {
     395                 :     179978 :     JL_GC_PUSH1(&a);
     396                 :     179978 :     size_t i, l = jl_array_len(a);
     397                 :     179978 :     _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_data(a);
     398         [ +  + ]:     179978 :     unsigned height = tparam & 2 ? jl_supertype_height((jl_datatype_t*)ty) : 0;
     399         [ +  + ]:   18002500 :     for (i = 0; i < l; i += 2) {
     400                 :   17829900 :         jl_value_t *t = jl_atomic_load_relaxed(&data[i]);
     401                 :            :         JL_GC_PROMISE_ROOTED(t);
     402   [ +  -  +  + ]:   17829900 :         if (t == jl_nothing || t == NULL)
     403                 :   12767500 :             continue;
     404         [ +  + ]:    5062410 :         if (tparam & 2) {
     405                 :    1088140 :             jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i + 1]);
     406                 :            :             JL_GC_PROMISE_ROOTED(ml);
     407   [ +  +  +  + ]:    1473160 :             if (ty == (jl_value_t*)jl_any_type || // easy case: Any always matches
     408                 :     385021 :                 tname_intersection((jl_datatype_t*)ty, (jl_typename_t*)t, height)) {
     409         [ +  + ]:     841753 :                 if (!jl_typemap_intersection_visitor(ml, offs + 1, closure))
     410                 :         69 :                     goto exit;
     411                 :            :             }
     412                 :            :         }
     413                 :            :         else {
     414                 :            :             // `t` is a leaftype, so intersection test becomes subtype
     415   [ +  +  +  +  :    7723070 :             if (ty == (jl_value_t*)jl_any_type || // easy case: Any always matches
                   +  + ]
     416         [ +  + ]:    3748800 :                 (tparam & 1
     417   [ +  +  +  + ]:    2770140 :                  ? (jl_typeof(t) == ty || jl_isa(t, ty)) // (Type{t} <: ty), where is_leaf_type(t) => isa(t, ty)
     418   [ +  -  +  + ]:     978659 :                  : (t == ty || jl_subtype(t, ty)))) {
     419                 :     647798 :                 jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i + 1]);
     420                 :            :                 JL_GC_PROMISE_ROOTED(ml);
     421                 :            :                 // NOTE: ml might be NULL if we're racing with the thread that's inserting the item
     422   [ +  -  +  + ]:     647798 :                 if (ml != NULL && !jl_typemap_intersection_visitor(ml, offs + 1, closure))
     423                 :       7365 :                     goto exit;
     424                 :            :             }
     425                 :            :         }
     426                 :            :     }
     427                 :     172544 :     JL_GC_POP();
     428                 :     172544 :     return 1;
     429                 :            : 
     430                 :       7434 : exit:
     431                 :       7434 :     JL_GC_POP();
     432                 :       7434 :     return 0;
     433                 :            : }
     434                 :            : 
     435                 :            : // calls fptr on each jl_typemap_entry_t in cache in sort order
     436                 :            : // for which type ∩ ml->type != Union{}, until fptr return false
     437                 :    2668490 : static int jl_typemap_intersection_node_visitor(jl_typemap_entry_t *ml, struct typemap_intersection_env *closure)
     438                 :            : {
     439                 :            :     // slow-path scan everything in ml
     440                 :            :     // mark this `register` because (for branch prediction)
     441                 :            :     // that can be absolutely critical for speed
     442                 :    2668490 :     register jl_typemap_intersection_visitor_fptr fptr = closure->fptr;
     443         [ +  + ]:    8336520 :     while (ml != (void*)jl_nothing) {
     444         [ +  + ]:    5676790 :         if (closure->type == (jl_value_t*)ml->sig) {
     445                 :            :             // fast-path for the intersection of a type with itself
     446         [ +  - ]:      62757 :             if (closure->env)
     447                 :      62757 :                 closure->env = jl_outer_unionall_vars((jl_value_t*)ml->sig);
     448                 :      62757 :             closure->ti = closure->type;
     449                 :      62757 :             closure->issubty = 1;
     450         [ -  + ]:      62757 :             if (!fptr(ml, closure))
     451                 :          0 :                 return 0;
     452                 :            :         }
     453                 :            :         else {
     454                 :    5614030 :             jl_svec_t **penv = NULL;
     455         [ +  - ]:    5614030 :             if (closure->env) {
     456                 :    5614030 :                 closure->env = jl_emptysvec;
     457                 :    5614030 :                 penv = &closure->env;
     458                 :            :             }
     459                 :    5614030 :             closure->ti = jl_type_intersection_env_s(closure->type, (jl_value_t*)ml->sig, penv, &closure->issubty);
     460         [ +  + ]:    5614030 :             if (closure->ti != (jl_value_t*)jl_bottom_type) {
     461                 :            :                 // In some corner cases type intersection is conservative and returns something
     462                 :            :                 // for intersect(A, B) even though A is a dispatch tuple and !(A <: B).
     463                 :            :                 // For dispatch purposes in such a case we know there's no match. This check
     464                 :            :                 // fixes issue #30394.
     465   [ +  +  +  + ]:    1036530 :                 if (closure->issubty || !jl_is_dispatch_tupletype(closure->type))
     466         [ +  + ]:    1036370 :                     if (!fptr(ml, closure))
     467                 :       8758 :                         return 0;
     468                 :            :             }
     469                 :            :         }
     470                 :    5668030 :         ml = jl_atomic_load_relaxed(&ml->next);
     471                 :            :     }
     472                 :    2659730 :     return 1;
     473                 :            : }
     474                 :            : 
     475                 :    2683810 : int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
     476                 :            :                                     struct typemap_intersection_env *closure)
     477                 :            : {
     478                 :    2683810 :     jl_value_t *ttypes = jl_unwrap_unionall(closure->type);
     479         [ -  + ]:    2683810 :     assert(jl_is_datatype(ttypes));
     480                 :            :     //TODO: fast-path for leaf-type tuples?
     481                 :            :     //if (ttypes->isdispatchtuple) {
     482                 :            :     //    register jl_typemap_intersection_visitor_fptr fptr = closure->fptr;
     483                 :            :     //        struct jl_typemap_assoc search = {(jl_value_t*)closure->type, world, closure->env, 0, ~(size_t)0};
     484                 :            :     //        jl_typemap_entry_t *ml = jl_typemap_assoc_by_type(map, search, offs, /*subtype*/1);
     485                 :            :     //        if (ml) {
     486                 :            :     //            closure->env = search->env;
     487                 :            :     //            if (!fptr(ml, closure))
     488                 :            :     //                return 0;
     489                 :            :     //        }
     490                 :            :     //    }
     491                 :            :     //    return 1;
     492                 :            :     //}
     493         [ +  + ]:    2683810 :     if (jl_typeof(map) == (jl_value_t *)jl_typemap_level_type) {
     494                 :     384778 :         jl_typemap_level_t *cache = (jl_typemap_level_t*)map;
     495                 :            :         jl_value_t *ty;
     496                 :     384778 :         size_t l = jl_nparams(ttypes);
     497   [ +  +  +  + ]:     384778 :         if (closure->va && l <= offs + 1) {
     498                 :        180 :             ty = closure->va;
     499                 :            :         }
     500         [ +  + ]:     384598 :         else if (l > offs) {
     501                 :     383505 :             ty = jl_tparam(ttypes, offs);
     502                 :            :         }
     503                 :            :         else {
     504                 :       1093 :             ty = NULL;
     505                 :            :         }
     506         [ +  + ]:     384778 :         if (ty == (jl_value_t*)jl_typeofbottom_type)
     507                 :          4 :             ty = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
     508         [ +  + ]:     384778 :         if (ty) {
     509         [ +  + ]:     383984 :             while (jl_is_typevar(ty))
     510                 :        299 :                 ty = ((jl_tvar_t*)ty)->ub;
     511                 :     383685 :             jl_value_t *typetype = jl_unwrap_unionall(ty);
     512         [ +  + ]:     383685 :             typetype = jl_is_type_type(typetype) ? jl_tparam0(typetype) : NULL;
     513                 :            :             // approxify the tparam until we have a valid type
     514         [ +  + ]:     383685 :             if (jl_has_free_typevars(ty)) {
     515                 :       3101 :                 ty = jl_unwrap_unionall(ty);
     516         [ +  + ]:       3101 :                 if (jl_is_datatype(ty))
     517                 :       2956 :                     ty = ((jl_datatype_t*)ty)->name->wrapper;
     518                 :            :                 else
     519                 :        145 :                     ty = (jl_value_t*)jl_any_type;
     520                 :            :             }
     521                 :     383685 :             jl_array_t *targ = jl_atomic_load_relaxed(&cache->targ);
     522         [ +  + ]:     383685 :             if (targ != (jl_array_t*)jl_an_empty_vec_any) {
     523   [ +  +  +  + ]:      82629 :                 if (typetype && !jl_has_free_typevars(typetype)) {
     524         [ +  + ]:      61438 :                     if (is_cache_leaf(typetype, 1)) {
     525                 :            :                         // direct lookup of leaf types
     526                 :      39135 :                         jl_typemap_t *ml = mtcache_hash_lookup(targ, typetype);
     527         [ +  + ]:      39135 :                         if (ml != jl_nothing) {
     528         [ +  + ]:      15111 :                             if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0;
     529                 :            :                         }
     530                 :            :                     }
     531                 :            :                 }
     532                 :            :                 else {
     533                 :            :                     // else an array scan is required to check subtypes
     534                 :            :                     // first, fast-path: optimized pre-intersection test to see if `ty` could intersect with any Type
     535   [ +  +  +  + ]:      21191 :                     if (typetype || !jl_has_empty_intersection((jl_value_t*)jl_type_type, ty)) {
     536                 :      13735 :                         targ = jl_atomic_load_relaxed(&cache->targ); // may be GC'd during type-intersection
     537         [ +  + ]:      13735 :                         if (!jl_typemap_intersection_array_visitor(targ, ty, 1, offs, closure)) return 0;
     538                 :            :                     }
     539                 :            :                 }
     540                 :            :             }
     541                 :     382594 :             jl_array_t *cachearg1 = jl_atomic_load_relaxed(&cache->arg1);
     542         [ +  + ]:     382594 :             if (cachearg1 != (jl_array_t*)jl_an_empty_vec_any) {
     543         [ +  + ]:     277685 :                 if (is_cache_leaf(ty, 0)) {
     544                 :            :                     // direct lookup of leaf types
     545                 :     202958 :                     jl_typemap_t *ml = mtcache_hash_lookup(cachearg1, ty);
     546         [ +  + ]:     202958 :                     if (ml != jl_nothing) {
     547         [ +  + ]:     159211 :                         if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0;
     548                 :            :                     }
     549                 :            :                 }
     550                 :            :                 else {
     551                 :            :                     // else an array scan is required to check subtypes
     552         [ +  + ]:      74727 :                     if (!jl_typemap_intersection_array_visitor(cachearg1, ty, 0, offs, closure)) return 0;
     553                 :            :                 }
     554                 :            :             }
     555                 :     368466 :             jl_array_t *tname = jl_atomic_load_relaxed(&cache->tname);
     556         [ +  + ]:     368466 :             if (tname != (jl_array_t*)jl_an_empty_vec_any) {
     557         [ +  + ]:     126026 :                 jl_value_t *name = typetype ? jl_type_extract_name(typetype) : NULL;
     558   [ +  +  +  + ]:     192643 :                 if (name && !jl_is_typevar(typetype)) {
     559                 :            :                     // semi-direct lookup of types
     560                 :            :                     // TODO: the possibility of encountering `Type{Union{}}` in this intersection may
     561                 :            :                     // be forcing us to do some extra work here whenever we see a typevar, even though
     562                 :            :                     // the likelyhood of that value actually occurring is frequently likely to be
     563                 :            :                     // zero (or result in an ambiguous match)
     564                 :      66649 :                     jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
     565         [ +  - ]:      66649 :                     if (jl_type_extract_name_precise(typetype, 1)) {
     566                 :            :                         // just consider the type and its direct super types
     567                 :     115594 :                         while (1) {
     568                 :     182243 :                             tname = jl_atomic_load_relaxed(&cache->tname); // reload after callback
     569                 :     182243 :                             jl_typemap_t *ml = mtcache_hash_lookup(tname, (jl_value_t*)super->name);
     570         [ +  + ]:     182243 :                             if (ml != jl_nothing) {
     571         [ +  + ]:     119604 :                                 if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0;
     572                 :            :                             }
     573         [ +  + ]:     182211 :                             if (super == jl_any_type)
     574                 :      66617 :                                 break;
     575                 :     115594 :                             super = super->super;
     576                 :            :                         }
     577                 :            :                     }
     578                 :            :                     else {
     579                 :            :                         // consider all of the possible subtypes
     580         [ #  # ]:          0 :                         if (!jl_typemap_intersection_array_visitor(tname, (jl_value_t*)super, 3, offs, closure)) return 0;
     581                 :            :                     }
     582                 :            :                 }
     583                 :            :                 else {
     584                 :            :                     // else an array scan is required to check subtypes
     585                 :            :                     // first, fast-path: optimized pre-intersection test to see if `ty` could intersect with any Type
     586   [ +  +  +  + ]:      59377 :                     if (name || !jl_has_empty_intersection((jl_value_t*)jl_type_type, ty)) {
     587                 :      16445 :                         tname = jl_atomic_load_relaxed(&cache->tname);  // may be GC'd during type-intersection
     588         [ +  + ]:      16445 :                         if (!jl_typemap_intersection_array_visitor(tname, (jl_value_t*)jl_any_type, 3, offs, closure)) return 0;
     589                 :            :                     }
     590                 :            :                 }
     591                 :            :             }
     592                 :     368365 :             jl_array_t *name1 = jl_atomic_load_relaxed(&cache->name1);
     593         [ +  + ]:     368365 :             if (name1 != (jl_array_t*)jl_an_empty_vec_any) {
     594                 :     193091 :                 jl_value_t *name = jl_type_extract_name(ty);
     595         [ +  + ]:     193091 :                 if (name) {
     596                 :     187186 :                     jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
     597         [ +  + ]:     187186 :                     if (jl_type_extract_name_precise(ty, 0)) {
     598                 :            :                         // direct lookup of concrete types
     599                 :     239537 :                         while (1) {
     600                 :     357557 :                             name1 = jl_atomic_load_relaxed(&cache->name1); // reload after callback
     601                 :     357557 :                             jl_typemap_t *ml = mtcache_hash_lookup(name1, (jl_value_t*)super->name);
     602         [ +  + ]:     357557 :                             if (ml != jl_nothing) {
     603         [ -  + ]:     113088 :                                 if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0;
     604                 :            :                             }
     605         [ +  + ]:     357557 :                             if (super == jl_any_type)
     606                 :     118020 :                                 break;
     607                 :     239537 :                             super = super->super;
     608                 :            :                         }
     609                 :            :                     }
     610                 :            :                     else {
     611                 :            :                         // consider all of the possible subtypes too
     612         [ -  + ]:      69166 :                         if (!jl_typemap_intersection_array_visitor(name1, (jl_value_t*)super, 2, offs, closure)) return 0;
     613                 :            :                     }
     614                 :            :                 }
     615                 :            :                 else {
     616                 :            :                     // else an array scan is required to check subtypes
     617         [ -  + ]:       5905 :                     if (!jl_typemap_intersection_array_visitor(name1, (jl_value_t*)jl_any_type, 2, offs, closure)) return 0;
     618                 :            :                 }
     619                 :            :             }
     620                 :            :         }
     621         [ -  + ]:     369458 :         if (!jl_typemap_intersection_node_visitor(jl_atomic_load_relaxed(&cache->linear), closure))
     622                 :          0 :             return 0;
     623                 :     369458 :         return jl_typemap_intersection_visitor(jl_atomic_load_relaxed(&cache->any), offs+1, closure);
     624                 :            :     }
     625                 :            :     else {
     626                 :    2299030 :         return jl_typemap_intersection_node_visitor(
     627                 :            :             (jl_typemap_entry_t*)map, closure);
     628                 :            :     }
     629                 :            : }
     630                 :            : 
     631                 :            : 
     632                 :            : /*
     633                 :            :   Method caches are divided into three parts: one for signatures where
     634                 :            :   the first argument is a singleton kind (Type{Foo}), one indexed by the
     635                 :            :   UID of the first argument's type in normal cases, and a fallback
     636                 :            :   table of everything else.
     637                 :            : 
     638                 :            :   Note that the "primary key" is the type of the first *argument*, since
     639                 :            :   there tends to be lots of variation there. The type of the 0th argument
     640                 :            :   (the function) is always the same for most functions.
     641                 :            : */
     642                 :     739319 : static jl_typemap_entry_t *jl_typemap_entry_assoc_by_type(
     643                 :            :         jl_typemap_entry_t *ml,
     644                 :            :         struct jl_typemap_assoc *search)
     645                 :            : {
     646                 :     739319 :     jl_value_t *types = search->types;
     647                 :            :     JL_GC_PROMISE_ROOTED(types);
     648                 :     739319 :     jl_value_t *unw = jl_unwrap_unionall((jl_value_t*)types);
     649                 :     739319 :     int isua = jl_is_unionall(types);
     650                 :     739319 :     size_t n = jl_nparams(unw);
     651         [ +  - ]:     739319 :     int typesisva = n == 0 ? 0 : jl_is_vararg(jl_tparam(unw, n-1));
     652         [ +  + ]:    1505240 :     for (; ml != (void*)jl_nothing; ml = jl_atomic_load_relaxed(&ml->next)) {
     653                 :     944172 :         size_t lensig = jl_nparams(jl_unwrap_unionall((jl_value_t*)ml->sig));
     654   [ +  +  +  +  :     944172 :         if (lensig == n || (ml->va && lensig <= n+1)) {
                   +  + ]
     655                 :     826295 :             int resetenv = 0, ismatch = 1;
     656   [ +  +  +  - ]:     826295 :             if (ml->simplesig != (void*)jl_nothing && !isua) {
     657                 :     781127 :                 size_t lensimplesig = jl_nparams(ml->simplesig);
     658   [ +  -  +  + ]:     781127 :                 int isva = lensimplesig > 0 && jl_is_vararg(jl_tparam(ml->simplesig, lensimplesig - 1));
     659   [ +  +  +  -  :     781127 :                 if (lensig == n || (isva && lensimplesig <= n + 1))
                   +  - ]
     660                 :     781127 :                     ismatch = sig_match_by_type_simple(jl_svec_data(((jl_datatype_t*)types)->parameters), n,
     661                 :            :                                                        ml->simplesig, lensimplesig, isva);
     662                 :            :                 else
     663                 :          0 :                     ismatch = 0;
     664                 :            :             }
     665                 :            : 
     666         [ +  + ]:     826295 :             if (ismatch == 0)
     667                 :            :                 ; // nothing
     668   [ -  +  -  -  :     423247 :             else if (ml->isleafsig && !typesisva && !isua)
                   -  - ]
     669                 :          0 :                 ismatch = sig_match_by_type_leaf(jl_svec_data(((jl_datatype_t*)types)->parameters),
     670                 :            :                                                  ml->sig, lensig);
     671   [ +  +  +  +  :     423247 :             else if (ml->issimplesig && !typesisva && !isua)
                   +  - ]
     672                 :     261276 :                 ismatch = sig_match_by_type_simple(jl_svec_data(((jl_datatype_t*)types)->parameters), n,
     673                 :     261276 :                                                    ml->sig, lensig, ml->va);
     674                 :            :             else {
     675         [ +  + ]:     161971 :                 ismatch = jl_subtype_matching(types, (jl_value_t*)ml->sig, search->env ? &search->env : NULL);
     676   [ +  +  +  + ]:     161971 :                 if (ismatch && search->env)
     677                 :      92206 :                     resetenv = 1;
     678                 :            :             }
     679                 :            : 
     680         [ +  + ]:     826295 :             if (ismatch) {
     681                 :            :                 size_t i, l;
     682         [ +  + ]:     204915 :                 for (i = 0, l = jl_svec_len(ml->guardsigs); i < l; i++) {
     683                 :            :                     // see corresponding code in jl_typemap_entry_assoc_exact
     684         [ +  + ]:      26419 :                     if (jl_subtype(types, jl_svecref(ml->guardsigs, i))) {
     685                 :       1466 :                         ismatch = 0;
     686                 :       1466 :                         break;
     687                 :            :                     }
     688                 :            :                 }
     689         [ +  + ]:     179962 :                 if (ismatch) {
     690         [ -  + ]:     178496 :                     if (search->world < ml->min_world) {
     691                 :            :                         // ignore method table entries that are part of a later world
     692         [ #  # ]:          0 :                         if (search->max_valid >= ml->min_world)
     693                 :          0 :                             search->max_valid = ml->min_world - 1;
     694                 :            :                     }
     695         [ +  + ]:     178496 :                     else if (search->world > ml->max_world) {
     696                 :            :                         // ignore method table entries that have been replaced in the current world
     697         [ +  - ]:        248 :                         if (search->min_valid <= ml->max_world)
     698                 :        248 :                             search->min_valid = ml->max_world + 1;
     699                 :            :                     }
     700                 :            :                     else {
     701                 :            :                         // intersect the env valid range with method's valid range
     702         [ +  - ]:     178248 :                         if (search->min_valid < ml->min_world)
     703                 :     178248 :                             search->min_valid = ml->min_world;
     704         [ -  + ]:     178248 :                         if (search->max_valid > ml->max_world)
     705                 :          0 :                             search->max_valid = ml->max_world;
     706                 :     178248 :                         return ml;
     707                 :            :                     }
     708                 :            :                 }
     709                 :            :             }
     710         [ +  + ]:     648047 :             if (resetenv)
     711                 :        230 :                 search->env = jl_emptysvec;
     712                 :            :         }
     713                 :            :     }
     714                 :     561071 :     return NULL;
     715                 :            : }
     716                 :            : 
     717                 :     113721 : static jl_typemap_entry_t *jl_typemap_entry_lookup_by_type(
     718                 :            :         jl_typemap_entry_t *ml, struct jl_typemap_assoc *search)
     719                 :            : {
     720         [ +  + ]:     441611 :     for (; ml != (void*)jl_nothing; ml = jl_atomic_load_relaxed(&ml->next)) {
     721   [ +  -  +  + ]:     327890 :         if (search->world < ml->min_world || search->world > ml->max_world)
     722                 :         14 :             continue;
     723                 :            :         // unroll the first few cases here, to the extent that is possible to do fast and easily
     724                 :     327876 :         jl_value_t *types = search->types;
     725                 :            :         JL_GC_PROMISE_ROOTED(types);
     726                 :     327876 :         jl_value_t *a = jl_unwrap_unionall(types);
     727                 :     327876 :         jl_value_t *b = jl_unwrap_unionall((jl_value_t*)ml->sig);
     728                 :     327876 :         size_t na = jl_nparams(a);
     729                 :     327876 :         size_t nb = jl_nparams(b);
     730   [ +  -  +  + ]:     327876 :         int va_a = na > 0 && jl_is_vararg(jl_tparam(a, na - 1));
     731   [ +  -  +  + ]:     327876 :         int va_b = nb > 0 && jl_is_vararg(jl_tparam(b, nb - 1));
     732   [ +  +  +  + ]:     327876 :         if (!va_a && !va_b) {
     733         [ +  + ]:     309321 :             if (na != nb)
     734                 :     147535 :                 continue;
     735                 :            :         }
     736   [ +  -  +  - ]:     180341 :         if (na - va_a > 0 && nb - va_b > 0) {
     737         [ +  + ]:     180341 :             if (jl_obviously_unequal(jl_tparam(a, 0), jl_tparam(b, 0)))
     738                 :      52540 :                 continue;
     739   [ +  +  +  + ]:     127801 :             if (na - va_a > 1 && nb - va_b > 1) {
     740         [ +  + ]:     125052 :                 if (jl_obviously_unequal(jl_tparam(a, 1), jl_tparam(b, 1)))
     741                 :      50330 :                     continue;
     742   [ +  +  +  + ]:      74722 :                 if (na - va_a > 2 && nb - va_b > 2) {
     743         [ +  + ]:      62699 :                     if (jl_obviously_unequal(jl_tparam(a, 2), jl_tparam(b, 2)))
     744                 :      33189 :                         continue;
     745                 :            :                 }
     746                 :            :             }
     747                 :            :         }
     748         [ -  + ]:      44282 :         if (jl_types_equal(types, (jl_value_t*)ml->sig))
     749                 :          0 :             return ml;
     750                 :            :     }
     751                 :     113721 :     return NULL;
     752                 :            : }
     753                 :            : 
     754                 :            : 
     755                 :            : // this is the general entry point for looking up a type in the cache
     756                 :            : // as a subtype, or with type_equal
     757                 :    1015930 : jl_typemap_entry_t *jl_typemap_assoc_by_type(
     758                 :            :         jl_typemap_t *ml_or_cache,
     759                 :            :         struct jl_typemap_assoc *search,
     760                 :            :         int8_t offs, uint8_t subtype)
     761                 :            : {
     762         [ +  + ]:    1015930 :     if (jl_typeof(ml_or_cache) == (jl_value_t *)jl_typemap_level_type) {
     763                 :     328758 :         jl_typemap_level_t *cache = (jl_typemap_level_t*)ml_or_cache;
     764                 :            :         // called object is the primary key for constructors, otherwise first argument
     765                 :            :         jl_value_t *ty;
     766                 :     328758 :         jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)search->types);
     767                 :            :         JL_GC_PROMISE_ROOTED(ttypes);
     768         [ -  + ]:     328758 :         assert(jl_is_datatype(ttypes));
     769                 :     328758 :         size_t l = jl_nparams(ttypes);
     770                 :     328758 :         int isva = 0;
     771                 :            :         // compute the type at offset `offs` into `types`, which may be a Vararg
     772         [ +  + ]:     328758 :         if (l <= offs + 1) {
     773                 :      98617 :             ty = jl_tparam(ttypes, l - 1);
     774         [ +  + ]:      98617 :             if (jl_is_vararg(ty)) {
     775                 :         47 :                 ty = jl_unwrap_vararg(ty);
     776                 :         47 :                 isva = 1;
     777                 :            :             }
     778         [ +  + ]:      98570 :             else if (l <= offs) {
     779                 :      15899 :                 ty = NULL;
     780                 :            :             }
     781                 :            :         }
     782         [ +  - ]:     230141 :         else if (l > offs) {
     783                 :     230141 :             ty = jl_tparam(ttypes, offs);
     784                 :            :         }
     785                 :            :         else {
     786                 :          0 :             ty = NULL;
     787                 :            :         }
     788         [ +  + ]:     328758 :         if (ty == (jl_value_t*)jl_typeofbottom_type)
     789                 :        112 :             ty = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
     790                 :            :         // If there is a type at offs, look in the optimized leaf type caches
     791   [ +  +  +  + ]:     328758 :         if (ty && !subtype) {
     792         [ +  + ]:      29625 :             if (jl_is_any(ty))
     793                 :       2562 :                 return jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&cache->any), search, offs + 1, subtype);
     794         [ +  + ]:      27063 :             if (isva) // in lookup mode, want to match Vararg exactly, not as a subtype
     795                 :         44 :                 ty = NULL;
     796                 :            :         }
     797         [ +  + ]:     326196 :         if (ty) {
     798                 :            :             // now look at the optimized leaftype caches
     799         [ +  + ]:     310253 :             if (jl_is_type_type(ty)) {
     800                 :     130000 :                 jl_value_t *a0 = jl_tparam0(ty);
     801         [ +  + ]:     130000 :                 if (is_cache_leaf(a0, 1)) {
     802                 :      60849 :                     jl_array_t *targ = jl_atomic_load_relaxed(&cache->targ);
     803         [ +  + ]:      60849 :                     if (targ != (jl_array_t*)jl_an_empty_vec_any) {
     804                 :      47124 :                         jl_typemap_t *ml = mtcache_hash_lookup(targ, a0);
     805         [ +  + ]:      47124 :                         if (ml != jl_nothing) {
     806                 :      14083 :                             jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     807         [ +  + ]:      14083 :                             if (li) return li;
     808                 :            :                         }
     809                 :            :                     }
     810         [ +  + ]:      51870 :                     if (!subtype) return NULL;
     811                 :            :                 }
     812                 :            :             }
     813         [ +  + ]:     297018 :             if (is_cache_leaf(ty, 0)) {
     814                 :     169876 :                 jl_array_t *cachearg1 = jl_atomic_load_relaxed(&cache->arg1);
     815         [ +  + ]:     169876 :                 if (cachearg1 != (jl_array_t*)jl_an_empty_vec_any) {
     816                 :     165234 :                     jl_typemap_t *ml = mtcache_hash_lookup(cachearg1, ty);
     817         [ +  + ]:     165234 :                     if (ml != jl_nothing) {
     818                 :      96092 :                         jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     819         [ +  + ]:      96092 :                         if (li) return li;
     820                 :            :                     }
     821                 :            :                 }
     822         [ +  + ]:     111554 :                 if (!subtype) return NULL;
     823                 :            :             }
     824                 :            :         }
     825   [ +  +  +  + ]:     241980 :         if (ty || subtype) {
     826                 :            :             // now look at the optimized TypeName caches
     827                 :     241282 :             jl_array_t *tname = jl_atomic_load_relaxed(&cache->tname);
     828         [ +  + ]:     241282 :             if (tname != (jl_array_t*)jl_an_empty_vec_any) {
     829   [ +  -  +  + ]:     161225 :                 jl_value_t *a0 = ty && jl_is_type_type(ty) ? jl_type_extract_name(jl_tparam0(ty)) : NULL;
     830         [ +  + ]:     161225 :                 if (a0) { // TODO: if we start analyzing Union types in jl_type_extract_name, then a0 might be over-approximated here, leading us to miss possible subtypes
     831                 :     111649 :                     jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper);
     832                 :     134264 :                     while (1) {
     833                 :     245913 :                         tname = jl_atomic_load_relaxed(&cache->tname); // reload after tree descent (which may hit safepoints)
     834                 :     245913 :                         jl_typemap_t *ml = mtcache_hash_lookup(tname, (jl_value_t*)super->name);
     835         [ +  + ]:     245913 :                         if (ml != (void*)jl_nothing) {
     836                 :     101592 :                             jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     837         [ +  + ]:     132932 :                             if (li) return li;
     838                 :            :                         }
     839   [ +  +  +  + ]:     201137 :                         if (super == jl_any_type || !subtype)
     840                 :            :                             break;
     841                 :     134264 :                         super = super->super;
     842                 :            :                     }
     843                 :            :                 }
     844                 :            :                 else {
     845   [ +  -  +  + ]:      49576 :                     if (!ty || !jl_has_empty_intersection((jl_value_t*)jl_type_type, ty)) {
     846                 :            :                         // couldn't figure out unique `a0` initial point, so scan all for matches
     847                 :       4694 :                         size_t i, l = jl_array_len(tname);
     848                 :       4694 :                         _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_ptr_data(tname);
     849                 :       4694 :                         JL_GC_PUSH1(&tname);
     850         [ +  + ]:     205977 :                         for (i = 1; i < l; i += 2) {
     851                 :     203377 :                             jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i]);
     852   [ +  +  -  + ]:     203377 :                             if (ml == NULL || ml == jl_nothing)
     853                 :     128933 :                                 continue;
     854                 :      74444 :                             jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     855         [ +  + ]:      74444 :                             if (li) {
     856                 :       2094 :                                 JL_GC_POP();
     857                 :       2094 :                                 return li;
     858                 :            :                             }
     859                 :            :                         }
     860                 :       2600 :                         JL_GC_POP();
     861                 :            :                     }
     862                 :            :                 }
     863                 :            :             }
     864                 :     194412 :             jl_array_t *name1 = jl_atomic_load_relaxed(&cache->name1);
     865         [ +  + ]:     194412 :             if (name1 != (jl_array_t*)jl_an_empty_vec_any) {
     866         [ +  + ]:      49358 :                 if (ty) {
     867                 :      49286 :                     jl_value_t *a0 = jl_type_extract_name(ty);
     868         [ +  + ]:      49286 :                     if (a0) { // TODO: if we start analyzing Union types in jl_type_extract_name, then a0 might be over-approximated here, leading us to miss possible subtypes
     869                 :      48585 :                         jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper);
     870                 :      25535 :                         while (1) {
     871                 :      74120 :                             name1 = jl_atomic_load_relaxed(&cache->name1); // reload after tree descent (which may hit safepoints)
     872                 :      74120 :                             jl_typemap_t *ml = mtcache_hash_lookup(name1, (jl_value_t*)super->name);
     873         [ +  + ]:      74120 :                             if (ml != (void*)jl_nothing) {
     874                 :            :                                 jl_typemap_entry_t *li =
     875                 :      38259 :                                     jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     876         [ +  + ]:      38259 :                                 if (li) return li;
     877                 :            :                             }
     878   [ +  +  +  + ]:      44874 :                             if (super == jl_any_type || !subtype)
     879                 :            :                                 break;
     880                 :      25535 :                             super = super->super;
     881                 :            :                         }
     882                 :            :                     }
     883                 :            :                 }
     884                 :            :                 else {
     885                 :            :                     // doing subtype, but couldn't figure out unique `ty`, so scan all for supertypes
     886                 :         72 :                     size_t i, l = jl_array_len(name1);
     887                 :         72 :                     _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_ptr_data(name1);
     888                 :         72 :                     JL_GC_PUSH1(&name1);
     889         [ +  + ]:        648 :                     for (i = 1; i < l; i += 2) {
     890                 :        576 :                         jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i]);
     891   [ +  +  -  + ]:        576 :                         if (ml == NULL || ml == jl_nothing)
     892                 :        504 :                             continue;
     893                 :         72 :                         jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     894         [ -  + ]:         72 :                         if (li) {
     895                 :          0 :                             JL_GC_POP();
     896                 :          0 :                             return li;
     897                 :            :                         }
     898                 :            :                     }
     899                 :         72 :                     JL_GC_POP();
     900                 :            :                 }
     901                 :            :             }
     902                 :            :         }
     903                 :            :         // Always check the list (since offs doesn't always start at 0)
     904         [ +  + ]:     165864 :         if (subtype) {
     905                 :     155062 :             jl_typemap_entry_t *li = jl_typemap_entry_assoc_by_type(jl_atomic_load_relaxed(&cache->linear), search);
     906         [ +  + ]:     155062 :             if (li) return li;
     907                 :     143330 :             return jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&cache->any), search, offs + 1, subtype);
     908                 :            :         }
     909                 :            :         else {
     910                 :      10802 :             return jl_typemap_entry_lookup_by_type(jl_atomic_load_relaxed(&cache->linear), search);
     911                 :            :         }
     912                 :            :     }
     913                 :            :     else {
     914                 :     687176 :         jl_typemap_entry_t *leaf = (jl_typemap_entry_t*)ml_or_cache;
     915                 :            :         return subtype ?
     916         [ +  + ]:     790095 :             jl_typemap_entry_assoc_by_type(leaf, search) :
     917                 :     102919 :             jl_typemap_entry_lookup_by_type(leaf, search);
     918                 :            :     }
     919                 :            : }
     920                 :            : 
     921                 :  126868000 : jl_typemap_entry_t *jl_typemap_entry_assoc_exact(jl_typemap_entry_t *ml, jl_value_t *arg1, jl_value_t **args, size_t n, size_t world)
     922                 :            : {
     923                 :            :     // some manually-unrolled common special cases
     924   [ +  +  +  +  :  126868000 :     while (ml->simplesig == (void*)jl_nothing && ml->guardsigs == jl_emptysvec && ml->isleafsig) {
                   -  + ]
     925                 :            :         // use a tight loop for as long as possible
     926   [ #  #  #  # ]:          0 :         if (world >= ml->min_world && world <= ml->max_world) {
     927   [ #  #  #  # ]:          0 :             if (n == jl_nparams(ml->sig) && jl_typeof(arg1) == jl_tparam(ml->sig, 0)) {
     928         [ #  # ]:          0 :                 if (n == 1)
     929                 :          0 :                     return ml;
     930         [ #  # ]:          0 :                 if (n == 2) {
     931         [ #  # ]:          0 :                     if (jl_typeof(args[0]) == jl_tparam(ml->sig, 1))
     932                 :          0 :                         return ml;
     933                 :            :                 }
     934         [ #  # ]:          0 :                 else if (n == 3) {
     935   [ #  #  #  # ]:          0 :                     if (jl_typeof(args[0]) == jl_tparam(ml->sig, 1) &&
     936                 :          0 :                         jl_typeof(args[1]) == jl_tparam(ml->sig, 2))
     937                 :          0 :                         return ml;
     938                 :            :                 }
     939                 :            :                 else {
     940         [ #  # ]:          0 :                     if (sig_match_leaf(arg1, args, jl_svec_data(ml->sig->parameters), n))
     941                 :          0 :                         return ml;
     942                 :            :                 }
     943                 :            :             }
     944                 :            :         }
     945                 :          0 :         ml = jl_atomic_load_relaxed(&ml->next);
     946         [ #  # ]:          0 :         if (ml == (void*)jl_nothing)
     947                 :          0 :             return NULL;
     948                 :            :     }
     949                 :            : 
     950         [ +  + ]:  246643000 :     for (; ml != (void*)jl_nothing; ml = jl_atomic_load_relaxed(&ml->next)) {
     951   [ +  +  +  + ]:  237674000 :         if (world < ml->min_world || world > ml->max_world)
     952                 :        380 :             continue; // ignore replaced methods
     953                 :  237673000 :         size_t lensig = jl_nparams(ml->sig);
     954   [ +  +  +  +  :  237673000 :         if (lensig == n || (ml->va && lensig <= n+1)) {
                   +  + ]
     955         [ +  + ]:  188830000 :             if (ml->simplesig != (void*)jl_nothing) {
     956                 :  128224000 :                 size_t lensimplesig = jl_nparams(ml->simplesig);
     957   [ +  -  +  + ]:  128224000 :                 int isva = lensimplesig > 0 && jl_is_vararg(jl_tparam(ml->simplesig, lensimplesig - 1));
     958   [ +  +  +  -  :  128224000 :                 if (lensig == n || (isva && lensimplesig <= n + 1)) {
                   +  - ]
     959         [ +  + ]:  128224000 :                     if (!sig_match_simple(arg1, args, n, jl_svec_data(ml->simplesig->parameters), isva, lensimplesig))
     960                 :   56910500 :                         continue;
     961                 :            :                 }
     962                 :            :                 else {
     963                 :          0 :                     continue;
     964                 :            :                 }
     965                 :            :             }
     966                 :            : 
     967         [ -  + ]:  131919000 :             if (ml->isleafsig) {
     968         [ #  # ]:          0 :                 if (!sig_match_leaf(arg1, args, jl_svec_data(ml->sig->parameters), n))
     969                 :          0 :                     continue;
     970                 :            :             }
     971         [ +  + ]:  131919000 :             else if (ml->issimplesig) {
     972         [ +  + ]:  101146000 :                 if (!sig_match_simple(arg1, args, n, jl_svec_data(ml->sig->parameters), ml->va, lensig))
     973                 :   11337200 :                     continue;
     974                 :            :             }
     975                 :            :             else {
     976         [ +  + ]:   30772700 :                 if (!jl_tuple1_isa(arg1, args, n, ml->sig))
     977                 :    2670090 :                     continue;
     978                 :            :             }
     979                 :            : 
     980                 :            :             size_t i, l;
     981         [ +  + ]:  117912000 :             if (ml->guardsigs != jl_emptysvec) {
     982         [ +  + ]:    5399200 :                 for (i = 0, l = jl_svec_len(ml->guardsigs); i < l; i++) {
     983                 :            :                     // checking guard entries require a more
     984                 :            :                     // expensive subtype check, since guard entries added for @nospecialize might be
     985                 :            :                     // abstract. this fixed issue #12967.
     986         [ +  + ]:    2738260 :                     if (jl_tuple1_isa(arg1, args, n, (jl_tupletype_t*)jl_svecref(ml->guardsigs, i))) {
     987                 :      12869 :                         goto nomatch;
     988                 :            :                     }
     989                 :            :                 }
     990                 :            :             }
     991                 :  117899000 :             return ml;
     992                 :      12869 : nomatch:
     993                 :      12869 :             continue;
     994                 :            :         }
     995                 :            :     }
     996                 :    8969540 :     return NULL;
     997                 :            : }
     998                 :            : 
     999                 :   14069100 : jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_value_t *arg1, jl_value_t **args, size_t n, int8_t offs, size_t world)
    1000                 :            : {
    1001         [ +  + ]:   14069100 :     if (n > offs) {
    1002         [ +  + ]:   14012600 :         jl_value_t *a1 = (offs == 0 ? arg1 : args[offs - 1]);
    1003                 :   14012600 :         jl_value_t *ty = jl_typeof(a1);
    1004         [ -  + ]:   14012600 :         assert(jl_is_datatype(ty));
    1005                 :   14012600 :         jl_array_t *targ = jl_atomic_load_relaxed(&cache->targ);
    1006   [ +  +  +  +  :   14012600 :         if (ty == (jl_value_t*)jl_datatype_type && targ != (jl_array_t*)jl_an_empty_vec_any && is_cache_leaf(a1, 1)) {
                   +  + ]
    1007                 :    1863260 :             jl_typemap_t *ml_or_cache = mtcache_hash_lookup(targ, a1);
    1008                 :    1863260 :             jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1009         [ +  + ]:   13919200 :             if (ml) return ml;
    1010                 :            :         }
    1011                 :   12532800 :         jl_array_t *cachearg1 = jl_atomic_load_relaxed(&cache->arg1);
    1012   [ +  +  +  + ]:   12532800 :         if (cachearg1 != (jl_array_t*)jl_an_empty_vec_any && is_cache_leaf(ty, 0)) {
    1013                 :    9282740 :             jl_typemap_t *ml_or_cache = mtcache_hash_lookup(cachearg1, ty);
    1014                 :    9282740 :             jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1015         [ +  + ]:    9282740 :             if (ml) return ml;
    1016                 :            :         }
    1017                 :    4599390 :         jl_array_t *tname = jl_atomic_load_relaxed(&cache->tname);
    1018   [ +  +  +  + ]:    4599390 :         if (jl_is_kind(ty) && tname != (jl_array_t*)jl_an_empty_vec_any) {
    1019                 :    3185360 :             jl_value_t *name = jl_type_extract_name(a1);
    1020         [ +  + ]:    3185360 :             if (name) {
    1021         [ +  + ]:    2626580 :                 if (ty != (jl_value_t*)jl_datatype_type)
    1022                 :    1759190 :                     a1 = jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
    1023                 :    1924630 :                 while (1) {
    1024                 :    4551220 :                     tname = jl_atomic_load_relaxed(&cache->tname); // reload after tree descent (which may hit safepoints)
    1025                 :    4551220 :                     jl_typemap_t *ml_or_cache = mtcache_hash_lookup(
    1026                 :    4551220 :                             tname, (jl_value_t*)((jl_datatype_t*)a1)->name);
    1027                 :    4551220 :                     jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1028         [ +  + ]:    4551220 :                     if (ml) return ml;
    1029         [ +  + ]:    1926840 :                     if (a1 == (jl_value_t*)jl_any_type)
    1030                 :       2212 :                         break;
    1031                 :    1924630 :                     a1 = (jl_value_t*)((jl_datatype_t*)a1)->super;
    1032                 :            :                 }
    1033                 :            :             }
    1034                 :            :             else {
    1035                 :            :                 // couldn't figure out unique `name` initial point, so must scan all for matches
    1036                 :     558778 :                 size_t i, l = jl_array_len(tname);
    1037                 :     558778 :                 _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_ptr_data(tname);
    1038                 :     558778 :                 JL_GC_PUSH1(&tname);
    1039         [ +  + ]:    3911900 :                 for (i = 1; i < l; i += 2) {
    1040                 :    3911670 :                     jl_typemap_t *ml_or_cache = jl_atomic_load_relaxed(&data[i]);
    1041   [ +  +  -  + ]:    3911670 :                     if (ml_or_cache == NULL || ml_or_cache == jl_nothing)
    1042                 :    2832540 :                         continue;
    1043                 :    1079140 :                     jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs + 1, world);
    1044         [ +  + ]:    1079140 :                     if (ml) {
    1045                 :     558551 :                         JL_GC_POP();
    1046                 :     558551 :                         return ml;
    1047                 :            :                     }
    1048                 :            :                 }
    1049                 :        227 :                 JL_GC_POP();
    1050                 :            :             }
    1051                 :            :         }
    1052                 :    1416460 :         jl_array_t *name1 = jl_atomic_load_relaxed(&cache->name1);
    1053         [ +  + ]:    1416460 :         if (name1 != (jl_array_t*)jl_an_empty_vec_any) {
    1054                 :      93953 :             while (1) {
    1055                 :    1058290 :                 name1 = jl_atomic_load_relaxed(&cache->name1); // reload after tree descent (which may hit safepoints)
    1056                 :    1058290 :                 jl_typemap_t *ml_or_cache = mtcache_hash_lookup(
    1057                 :    1058290 :                         name1, (jl_value_t*)((jl_datatype_t*)ty)->name);
    1058                 :    1058290 :                 jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1059         [ +  + ]:    1058290 :                 if (ml) return ml;
    1060         [ +  + ]:     118642 :                 if (ty == (jl_value_t*)jl_any_type)
    1061                 :      24689 :                     break;
    1062                 :      93953 :                 ty = (jl_value_t*)((jl_datatype_t*)ty)->super;
    1063                 :            :             }
    1064                 :            :         }
    1065                 :            :     }
    1066                 :     533394 :     jl_typemap_entry_t *linear = jl_atomic_load_relaxed(&cache->linear);
    1067         [ +  + ]:     533394 :     if (linear != (jl_typemap_entry_t*)jl_nothing) {
    1068                 :      56848 :         jl_typemap_entry_t *ml = jl_typemap_entry_assoc_exact(linear, arg1, args, n, world);
    1069         [ +  + ]:      56848 :         if (ml) return ml;
    1070                 :            :     }
    1071                 :     477106 :     jl_typemap_t *cacheany = jl_atomic_load_relaxed(&cache->any);
    1072         [ +  + ]:     477106 :     if (cacheany != (jl_typemap_t*)jl_nothing)
    1073                 :     472754 :         return jl_typemap_assoc_exact(cacheany, arg1, args, n, offs+1, world);
    1074                 :       4352 :     return NULL;
    1075                 :            : }
    1076                 :            : 
    1077                 :            : 
    1078                 :            : // ----- Method List Insertion Management ----- //
    1079                 :            : 
    1080                 :      70579 : static unsigned jl_typemap_list_count_locked(jl_typemap_entry_t *ml) JL_NOTSAFEPOINT
    1081                 :            : {
    1082                 :      70579 :     unsigned count = 0;
    1083         [ +  + ]:     280750 :     while (ml != (void*)jl_nothing) {
    1084                 :     210171 :         count++;
    1085                 :     210171 :         ml = jl_atomic_load_relaxed(&ml->next);
    1086                 :            :     }
    1087                 :      70579 :     return count;
    1088                 :            : }
    1089                 :            : 
    1090                 :            : static void jl_typemap_level_insert_(jl_typemap_t *map, jl_typemap_level_t *cache, jl_typemap_entry_t *newrec, int8_t offs);
    1091                 :            : 
    1092                 :       1394 : static jl_typemap_level_t *jl_new_typemap_level(void)
    1093                 :            : {
    1094                 :       1394 :     jl_task_t *ct = jl_current_task;
    1095                 :            :     jl_typemap_level_t *cache =
    1096                 :       1394 :         (jl_typemap_level_t*)jl_gc_alloc(ct->ptls, sizeof(jl_typemap_level_t),
    1097                 :            :                                          jl_typemap_level_type);
    1098                 :       1394 :     jl_atomic_store_relaxed(&cache->arg1, (jl_array_t*)jl_an_empty_vec_any);
    1099                 :       1394 :     jl_atomic_store_relaxed(&cache->targ, (jl_array_t*)jl_an_empty_vec_any);
    1100                 :       1394 :     jl_atomic_store_relaxed(&cache->name1, (jl_array_t*)jl_an_empty_vec_any);
    1101                 :       1394 :     jl_atomic_store_relaxed(&cache->tname, (jl_array_t*)jl_an_empty_vec_any);
    1102                 :       1394 :     jl_atomic_store_relaxed(&cache->linear, (jl_typemap_entry_t*)jl_nothing);
    1103                 :       1394 :     jl_atomic_store_relaxed(&cache->any, jl_nothing);
    1104                 :       1394 :     return cache;
    1105                 :            : }
    1106                 :            : 
    1107                 :       1394 : static jl_typemap_level_t *jl_method_convert_list_to_cache(
    1108                 :            :         jl_typemap_t *map, jl_typemap_entry_t *ml, int8_t offs)
    1109                 :            : {
    1110                 :       1394 :     jl_typemap_level_t *cache = jl_new_typemap_level();
    1111                 :       1394 :     jl_typemap_entry_t *next = NULL;
    1112                 :       1394 :     JL_GC_PUSH3(&cache, &next, &ml);
    1113         [ +  + ]:      19516 :     while (ml != (void*)jl_nothing) {
    1114                 :      18122 :         next = jl_atomic_load_relaxed(&ml->next);
    1115                 :      18122 :         jl_atomic_store_relaxed(&ml->next, (jl_typemap_entry_t*)jl_nothing);
    1116                 :            :         // n.b. this is being done concurrently with lookups!
    1117                 :            :         // TODO: is it safe to be doing this concurrently with lookups?
    1118                 :      18122 :         jl_typemap_level_insert_(map, cache, ml, offs);
    1119                 :      18122 :         ml = next;
    1120                 :            :     }
    1121                 :       1394 :     JL_GC_POP();
    1122                 :       1394 :     return cache;
    1123                 :            : }
    1124                 :            : 
    1125                 :      71403 : static void jl_typemap_list_insert_(
    1126                 :            :         jl_typemap_t *map, _Atomic(jl_typemap_entry_t*) *pml, jl_value_t *parent,
    1127                 :            :         jl_typemap_entry_t *newrec)
    1128                 :            : {
    1129                 :      71403 :     jl_typemap_entry_t *l = jl_atomic_load_relaxed(pml);
    1130         [ +  + ]:      91335 :     while ((jl_value_t*)l != jl_nothing) {
    1131   [ +  +  +  + ]:      65614 :         if (newrec->isleafsig || !l->isleafsig)
    1132   [ +  +  +  + ]:      55376 :             if (newrec->issimplesig || !l->issimplesig)
    1133                 :            :                 break;
    1134                 :      19932 :         pml = &l->next;
    1135                 :      19932 :         parent = (jl_value_t*)l;
    1136                 :      19932 :         l = jl_atomic_load_relaxed(&l->next);
    1137                 :            :     }
    1138                 :      71403 :     jl_atomic_store_relaxed(&newrec->next, l);
    1139                 :      71403 :     jl_gc_wb(newrec, l);
    1140                 :      71403 :     jl_atomic_store_release(pml, newrec);
    1141                 :      71403 :     jl_gc_wb(parent, newrec);
    1142                 :      71403 : }
    1143                 :            : 
    1144                 :     120923 : static void jl_typemap_insert_generic(
    1145                 :            :         jl_typemap_t *map, _Atomic(jl_typemap_t*) *pml, jl_value_t *parent,
    1146                 :            :         jl_typemap_entry_t *newrec, int8_t offs)
    1147                 :            : {
    1148                 :     120923 :     jl_typemap_t *ml = jl_atomic_load_relaxed(pml);
    1149         [ +  + ]:     120923 :     if (jl_typeof(ml) == (jl_value_t*)jl_typemap_level_type) {
    1150                 :      50344 :         jl_typemap_level_insert_(map, (jl_typemap_level_t*)ml, newrec, offs);
    1151                 :      50344 :         return;
    1152                 :            :     }
    1153                 :            : 
    1154                 :      70579 :     unsigned count = jl_typemap_list_count_locked((jl_typemap_entry_t*)ml);
    1155         [ +  + ]:      70579 :     if (count > MAX_METHLIST_COUNT) {
    1156                 :       1394 :         ml = (jl_typemap_t*)jl_method_convert_list_to_cache(
    1157                 :            :             map, (jl_typemap_entry_t*)ml, offs);
    1158                 :       1394 :         jl_atomic_store_release(pml, ml);
    1159                 :       1394 :         jl_gc_wb(parent, ml);
    1160                 :       1394 :         jl_typemap_level_insert_(map, (jl_typemap_level_t*)ml, newrec, offs);
    1161                 :       1394 :         return;
    1162                 :            :     }
    1163                 :            : 
    1164                 :      69185 :     jl_typemap_list_insert_(map, (_Atomic(jl_typemap_entry_t*)*)pml,
    1165                 :            :         parent, newrec);
    1166                 :            : }
    1167                 :            : 
    1168                 :      66535 : static void jl_typemap_array_insert_(
    1169                 :            :         jl_typemap_t *map, _Atomic(jl_array_t*) *pcache, jl_value_t *key, jl_typemap_entry_t *newrec,
    1170                 :            :         jl_value_t *parent, int8_t offs)
    1171                 :            : {
    1172                 :      66535 :     jl_array_t *cache = jl_atomic_load_relaxed(pcache);
    1173                 :      66535 :     _Atomic(jl_typemap_t*) *pml = mtcache_hash_lookup_bp(cache, key);
    1174         [ +  + ]:      66535 :     if (pml != NULL)
    1175                 :      43922 :         jl_typemap_insert_generic(map, pml, (jl_value_t*)cache, newrec, offs+1);
    1176                 :            :     else
    1177                 :      22613 :         mtcache_hash_insert(pcache, parent, key, (jl_typemap_t*)newrec);
    1178                 :      66535 : }
    1179                 :            : 
    1180                 :      69860 : static void jl_typemap_level_insert_(
    1181                 :            :         jl_typemap_t *map, jl_typemap_level_t *cache, jl_typemap_entry_t *newrec, int8_t offs)
    1182                 :            : {
    1183                 :      69860 :     jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)newrec->sig);
    1184                 :      69860 :     size_t l = jl_nparams(ttypes);
    1185                 :            :     // compute the type at offset `offs` into `sig`, which may be a Vararg
    1186                 :            :     jl_value_t *t1;
    1187                 :      69860 :     int isva = 0;
    1188         [ +  + ]:      69860 :     if (l <= offs + 1) {
    1189                 :      13961 :         t1 = jl_tparam(ttypes, l - 1);
    1190         [ +  + ]:      13961 :         if (jl_is_vararg(t1)) {
    1191                 :        127 :             isva = 1;
    1192                 :        127 :             t1 = jl_unwrap_vararg(t1);
    1193                 :            :         }
    1194         [ +  + ]:      13834 :         else if (l <= offs) {
    1195                 :        931 :             t1 = NULL;
    1196                 :            :         }
    1197                 :            :     }
    1198         [ +  - ]:      55899 :     else if (l > offs) {
    1199                 :      55899 :         t1 = jl_tparam(ttypes, offs);
    1200                 :            :     }
    1201                 :            :     else {
    1202                 :          0 :         t1 = NULL;
    1203                 :            :     }
    1204         [ +  + ]:      69860 :     if (t1 == (jl_value_t*)jl_typeofbottom_type)
    1205                 :         28 :         t1 = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
    1206                 :            :     // If the type at `offs` is Any, put it in the Any list
    1207   [ +  +  +  + ]:      69860 :     if (t1 && jl_is_any(t1)) {
    1208                 :       1107 :         jl_typemap_insert_generic(map, &cache->any, (jl_value_t*)cache, newrec, offs+1);
    1209                 :       1107 :         return;
    1210                 :            :     }
    1211                 :            :     // Don't put Varargs in the optimized caches (too hard to handle in lookup and bp)
    1212   [ +  +  +  + ]:      68753 :     if (t1 && !isva) {
    1213                 :            :         // try to put in leaf type caches
    1214         [ +  + ]:      67716 :         if (jl_is_type_type(t1)) {
    1215                 :            :             // if the argument is Type{...}, this method has specializations for singleton kinds
    1216                 :            :             // and we use the table indexed for that purpose.
    1217                 :      18540 :             jl_value_t *a0 = jl_tparam0(t1);
    1218         [ +  + ]:      18540 :             if (is_cache_leaf(a0, 1)) {
    1219                 :       7498 :                 jl_typemap_array_insert_(map, &cache->targ, a0, newrec, (jl_value_t*)cache, offs);
    1220                 :       7498 :                 return;
    1221                 :            :             }
    1222                 :            :         }
    1223         [ +  + ]:      60218 :         if (is_cache_leaf(t1, 0)) {
    1224                 :      35096 :             jl_typemap_array_insert_(map, &cache->arg1, t1, newrec, (jl_value_t*)cache, offs);
    1225                 :      35096 :             return;
    1226                 :            :         }
    1227                 :            : 
    1228                 :            :         // try to put in TypeName caches
    1229                 :            :         jl_value_t *a0;
    1230                 :      25122 :         t1 = jl_unwrap_unionall(t1);
    1231         [ +  + ]:      25122 :         if (jl_is_type_type(t1)) {
    1232                 :      12062 :             a0 = jl_type_extract_name(jl_tparam0(t1));
    1233         [ +  + ]:      12062 :             jl_datatype_t *super = a0 ? (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper) : jl_any_type;
    1234                 :      12062 :             jl_typemap_array_insert_(map, &cache->tname, (jl_value_t*)super->name, newrec, (jl_value_t*)cache, offs);
    1235                 :      12062 :             return;
    1236                 :            :         }
    1237                 :      13060 :         a0 = jl_type_extract_name(t1);
    1238   [ +  +  +  - ]:      13060 :         if (a0 && a0 != (jl_value_t*)jl_any_type->name) {
    1239                 :      11879 :             jl_typemap_array_insert_(map, &cache->name1, a0, newrec, (jl_value_t*)cache, offs);
    1240                 :      11879 :             return;
    1241                 :            :         }
    1242                 :            :     }
    1243                 :       2218 :     jl_typemap_list_insert_(map, &cache->linear, (jl_value_t*)cache, newrec);
    1244                 :            : }
    1245                 :            : 
    1246                 :     199653 : jl_typemap_entry_t *jl_typemap_alloc(
    1247                 :            :         jl_tupletype_t *type, jl_tupletype_t *simpletype, jl_svec_t *guardsigs,
    1248                 :            :         jl_value_t *newvalue, size_t min_world, size_t max_world)
    1249                 :            : {
    1250                 :     199653 :     jl_task_t *ct = jl_current_task;
    1251   [ +  -  +  - ]:     199653 :     assert(min_world > 0 && max_world > 0);
    1252         [ +  + ]:     199653 :     if (!simpletype)
    1253                 :     152670 :         simpletype = (jl_tupletype_t*)jl_nothing;
    1254                 :     199653 :     jl_value_t *ttype = jl_unwrap_unionall((jl_value_t*)type);
    1255         [ -  + ]:     199653 :     assert(jl_is_tuple_type(ttype));
    1256                 :            :     // compute the complexity of this type signature
    1257                 :     199653 :     int isva = jl_is_va_tuple((jl_datatype_t*)ttype);
    1258                 :     199653 :     int issimplesig = !jl_is_unionall(type); // a TypeVar environment needs a complex matching test
    1259   [ +  +  +  + ]:     199653 :     int isleafsig = issimplesig && !isva; // entirely leaf types don't need to be sorted
    1260                 :            :     size_t i, l;
    1261   [ +  +  +  + ]:     758322 :     for (i = 0, l = jl_nparams(ttype); i < l && issimplesig; i++) {
    1262                 :     558669 :         jl_value_t *decl = jl_tparam(ttype, i);
    1263         [ +  + ]:     558669 :         if (jl_is_kind(decl))
    1264                 :        507 :             isleafsig = 0; // Type{} may have a higher priority than a kind
    1265         [ +  + ]:     558162 :         else if (jl_is_type_type(decl))
    1266                 :      50821 :             isleafsig = 0; // Type{} may need special processing to compute the match
    1267         [ +  + ]:     507341 :         else if (jl_is_vararg(decl))
    1268                 :       2768 :             isleafsig = 0; // makes iteration easier when the endpoints are the same
    1269         [ +  + ]:     504573 :         else if (decl == (jl_value_t*)jl_any_type)
    1270                 :      22897 :             isleafsig = 0; // Any needs to go in the general cache
    1271         [ +  + ]:     481676 :         else if (!jl_is_concrete_type(decl)) // anything else needs to go through the general subtyping test
    1272                 :      33380 :             isleafsig = issimplesig = 0;
    1273                 :            :     }
    1274                 :            : 
    1275                 :            :     jl_typemap_entry_t *newrec =
    1276                 :     199653 :         (jl_typemap_entry_t*)jl_gc_alloc(ct->ptls, sizeof(jl_typemap_entry_t),
    1277                 :            :                                          jl_typemap_entry_type);
    1278                 :     199653 :     newrec->sig = type;
    1279                 :     199653 :     newrec->simplesig = simpletype;
    1280                 :     199653 :     newrec->func.value = newvalue;
    1281                 :     199653 :     newrec->guardsigs = guardsigs;
    1282                 :     199653 :     jl_atomic_store_relaxed(&newrec->next, (jl_typemap_entry_t*)jl_nothing);
    1283                 :     199653 :     newrec->min_world = min_world;
    1284                 :     199653 :     newrec->max_world = max_world;
    1285                 :     199653 :     newrec->va = isva;
    1286                 :     199653 :     newrec->issimplesig = issimplesig;
    1287                 :     199653 :     newrec->isleafsig = isleafsig;
    1288                 :     199653 :     return newrec;
    1289                 :            : }
    1290                 :            : 
    1291                 :      75894 : void jl_typemap_insert(_Atomic(jl_typemap_t *) *pcache, jl_value_t *parent,
    1292                 :            :         jl_typemap_entry_t *newrec, int8_t offs)
    1293                 :            : {
    1294                 :      75894 :     jl_typemap_t *cache = jl_atomic_load_relaxed(pcache);
    1295                 :      75894 :     jl_typemap_insert_generic(cache, pcache, parent, newrec, offs);
    1296                 :      75894 : }
    1297                 :            : 
    1298                 :            : #ifdef __cplusplus
    1299                 :            : }
    1300                 :            : #endif

Generated by: LCOV version 1.14