LCOV - code coverage report
Current view: top level - src - typemap.c (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 744 779 95.5 %
Date: 2022-07-16 23:42:53 Functions: 33 33 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 674 764 88.2 %

           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                 :     595936 : static int jl_is_any(jl_value_t *t1)
      20                 :            : {
      21         [ +  + ]:     597243 :     while (jl_is_typevar(t1))
      22                 :       1307 :         t1 = ((jl_tvar_t*)t1)->ub;
      23                 :     595936 :     return t1 == (jl_value_t*)jl_any_type;
      24                 :            : }
      25                 :            : 
      26                 :   16152400 : static jl_value_t *jl_type_extract_name(jl_value_t *t1 JL_PROPAGATES_ROOT)
      27                 :            : {
      28         [ +  + ]:   16152400 :     if (jl_is_unionall(t1))
      29                 :    6964460 :         t1 = jl_unwrap_unionall(t1);
      30         [ -  + ]:   16152400 :     if (jl_is_vararg(t1)) {
      31                 :          0 :         return jl_type_extract_name(jl_unwrap_vararg(t1));
      32                 :            :     }
      33         [ +  + ]:   16152400 :     else if (jl_is_typevar(t1)) {
      34                 :      45438 :         return jl_type_extract_name(((jl_tvar_t*)t1)->ub);
      35                 :            :     }
      36         [ +  + ]:   16107000 :     else if (jl_is_datatype(t1)) {
      37                 :   15276900 :         jl_datatype_t *dt = (jl_datatype_t*)t1;
      38         [ +  + ]:   15276900 :         if (!jl_is_kind(t1))
      39                 :   15242700 :             return (jl_value_t*)dt->name;
      40                 :      34243 :         return NULL;
      41                 :            :     }
      42         [ +  + ]:     830051 :     else if (jl_is_uniontype(t1)) {
      43                 :     822588 :         jl_uniontype_t *u1 = (jl_uniontype_t*)t1;
      44                 :     822588 :         jl_value_t *tn1 = jl_type_extract_name(u1->a);
      45                 :     822588 :         jl_value_t *tn2 = jl_type_extract_name(u1->b);
      46         [ +  + ]:     822588 :         if (tn1 == tn2)
      47                 :       4974 :             return tn1;
      48                 :            :         // TODO: if invariant is false, instead find the nearest common ancestor
      49                 :     817614 :         return NULL;
      50                 :            :     }
      51                 :       7463 :     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                 :    2455100 : static int jl_type_extract_name_precise(jl_value_t *t1, int invariant)
      57                 :            : {
      58         [ +  + ]:    2455100 :     if (jl_is_unionall(t1))
      59                 :     458265 :         t1 = jl_unwrap_unionall(t1);
      60         [ -  + ]:    2455100 :     if (jl_is_vararg(t1)) {
      61                 :          0 :         return jl_type_extract_name_precise(jl_unwrap_vararg(t1), invariant);
      62                 :            :     }
      63         [ -  + ]:    2455100 :     else if (jl_is_typevar(t1)) {
      64                 :          0 :         return jl_type_extract_name_precise(((jl_tvar_t*)t1)->ub, 0);
      65                 :            :     }
      66         [ +  + ]:    2455100 :     else if (jl_is_datatype(t1)) {
      67                 :    2453380 :         jl_datatype_t *dt = (jl_datatype_t*)t1;
      68   [ +  +  +  +  :    2453380 :         if ((invariant || !dt->name->abstract) && !jl_is_kind(t1))
                   +  - ]
      69                 :    1837600 :             return 1;
      70                 :     615781 :         return 0;
      71                 :            :     }
      72         [ +  - ]:       1727 :     else if (jl_is_uniontype(t1)) {
      73                 :       1727 :         jl_uniontype_t *u1 = (jl_uniontype_t*)t1;
      74         [ +  + ]:       1727 :         if (!jl_type_extract_name_precise(u1->a, invariant))
      75                 :        693 :             return 0;
      76         [ -  + ]:       1034 :         if (!jl_type_extract_name_precise(u1->b, invariant))
      77                 :          0 :             return 0;
      78                 :       1034 :         jl_value_t *tn1 = jl_type_extract_name(u1->a);
      79                 :       1034 :         jl_value_t *tn2 = jl_type_extract_name(u1->b);
      80         [ +  - ]:       1034 :         if (tn1 == tn2)
      81                 :       1034 :             return 1;
      82                 :          0 :         return 0;
      83                 :            :     }
      84                 :          0 :     return 1;
      85                 :            : }
      86                 :            : 
      87                 :            : 
      88                 :            : // ----- Type Signature Subtype Testing ----- //
      89                 :            : 
      90                 :        136 : static int sig_match_by_type_leaf(jl_value_t **types, jl_tupletype_t *sig, size_t n)
      91                 :            : {
      92                 :            :     size_t i;
      93         [ +  + ]:        286 :     for (i = 0; i < n; i++) {
      94                 :        284 :         jl_value_t *decl = jl_tparam(sig, i);
      95                 :        284 :         jl_value_t *a = types[i];
      96         [ +  + ]:        284 :         if (jl_is_type_type(a)) // decl is not Type, because it wouldn't be leafsig
      97                 :          1 :             a = jl_typeof(jl_tparam0(a));
      98         [ +  + ]:        284 :         if (!jl_types_equal(a, decl))
      99                 :        134 :             return 0;
     100                 :            :     }
     101                 :          2 :     return 1;
     102                 :            : }
     103                 :            : 
     104                 :   10169200 : 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         [ +  + ]:   10169200 :     if (va) lensig -= 1;
     108         [ +  + ]:   29880000 :     for (i = 0; i < lensig; i++) {
     109                 :   24595300 :         jl_value_t *decl = jl_tparam(sig, i);
     110                 :   24595300 :         jl_value_t *a = types[i];
     111         [ -  + ]:   24595300 :         jl_value_t *unw = jl_is_unionall(decl) ? ((jl_unionall_t*)decl)->body : decl;
     112         [ +  + ]:   24595300 :         if (jl_is_vararg(a))
     113                 :        144 :             return 0;
     114         [ +  + ]:   24595100 :         if (jl_is_type_type(unw)) {
     115                 :    1881040 :             jl_value_t *tp0 = jl_tparam0(unw);
     116         [ +  - ]:    1881040 :             if (jl_is_type_type(a)) {
     117         [ -  + ]:    1881040 :                 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         [ +  + ]:    1881040 :                 else if (!jl_types_equal(jl_tparam0(a), tp0)) {
     125                 :    1172290 :                     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         [ +  + ]:   22714100 :         else if (decl == (jl_value_t*)jl_any_type) {
     135                 :            :         }
     136                 :            :         else {
     137         [ +  + ]:   18801300 :             if (jl_is_type_type(a)) // decl is not Type, because it would be caught above
     138                 :    4415740 :                 a = jl_typeof(jl_tparam0(a));
     139         [ +  + ]:   18801300 :             if (!jl_types_equal(a, decl))
     140                 :    3712050 :                 return 0;
     141                 :            :         }
     142                 :            :     }
     143         [ +  + ]:    5284720 :     if (va) {
     144                 :     289031 :         jl_value_t *decl = jl_unwrap_unionall(jl_tparam(sig, i));
     145         [ -  + ]:     289031 :         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                 :     289031 :         jl_value_t *t = jl_unwrap_vararg(decl);
     150         [ -  + ]:     289031 :         if (jl_is_typevar(t))
     151                 :          0 :             t = ((jl_tvar_t*)t)->ub;
     152         [ +  + ]:    5113840 :         for (; i < n; i++) {
     153                 :    4835010 :             jl_value_t *ti = types[i];
     154   [ +  +  +  + ]:    4835010 :             if (i == n - 1 && jl_is_vararg(ti))
     155                 :       1782 :                 ti = jl_unwrap_vararg(ti);
     156         [ +  + ]:    4835010 :             if (!jl_subtype(ti, t))
     157                 :      10198 :                 return 0;
     158                 :            :         }
     159                 :     278833 :         return 1;
     160                 :            :     }
     161                 :    4995680 :     return 1;
     162                 :            : }
     163                 :            : 
     164                 :       1636 : 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         [ -  + ]:       1636 :     if (jl_typeof(arg1) != sig[0])
     169                 :          0 :         return 0;
     170         [ +  + ]:       9643 :     for (i = 1; i < n; i++) {
     171                 :       8053 :         jl_value_t *decl = sig[i];
     172                 :       8053 :         jl_value_t *a = args[i - 1];
     173         [ +  + ]:       8053 :         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                 :         46 :             return 0;
     179                 :            :         }
     180                 :            :     }
     181                 :       1590 :     return 1;
     182                 :            : }
     183                 :            : 
     184                 : 1411870000 : 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         [ +  + ]: 1411870000 :     if (va)
     190                 :  765703000 :         lensig -= 1;
     191         [ +  + ]: 2909290000 :     for (i = 0; i < lensig; i++) {
     192                 : 1648180000 :         jl_value_t *decl = sig[i];
     193         [ +  + ]: 1648180000 :         jl_value_t *a = (i == 0 ? arg1 : args[i - 1]);
     194   [ +  +  +  + ]: 1648180000 :         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                 : 1465080000 :             continue;
     200                 :            :         }
     201         [ -  + ]:  183099000 :         jl_value_t *unw = jl_is_unionall(decl) ? ((jl_unionall_t*)decl)->body : decl;
     202   [ +  +  +  + ]:  215440000 :         if (jl_is_type_type(unw) && jl_is_type(a)) {
     203                 :   39440800 :             jl_value_t *tp0 = jl_tparam0(unw);
     204         [ -  + ]:   39440800 :             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         [ +  + ]:   39440800 :                 if (a != tp0) {
     213                 :    8902220 :                     jl_datatype_t *da = (jl_datatype_t*)a;
     214                 :    8902220 :                     jl_datatype_t *dt = (jl_datatype_t*)tp0;
     215         [ +  + ]:   11927900 :                     while (jl_is_unionall(da))
     216                 :    3025720 :                         da = (jl_datatype_t*)((jl_unionall_t*)da)->body;
     217         [ +  + ]:   11743000 :                     while (jl_is_unionall(dt))
     218                 :    2840760 :                         dt = (jl_datatype_t*)((jl_unionall_t*)dt)->body;
     219   [ +  +  +  -  :    8902220 :                     if (jl_is_datatype(da) && jl_is_datatype(dt) && da->name != dt->name)
                   +  + ]
     220                 :    3472920 :                         return 0;
     221         [ +  + ]:    5429300 :                     if (!jl_types_equal(a, tp0))
     222                 :    3626750 :                         return 0;
     223                 :            :                 }
     224                 :            :             }
     225                 :            :         }
     226                 :            :         else {
     227                 :  143658000 :             return 0;
     228                 :            :         }
     229                 :            :     }
     230         [ +  + ]: 1261110000 :     if (va) {
     231                 :  762214000 :         jl_value_t *decl = sig[i];
     232         [ -  + ]:  762214000 :         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                 :  762214000 :         jl_value_t *t = jl_unwrap_vararg(decl);
     237         [ +  + ]: 3227630000 :         for (; i < n; i++) {
     238         [ +  + ]: 2465430000 :             jl_value_t *a = (i == 0 ? arg1 : args[i - 1]);
     239         [ +  + ]: 2465430000 :             if (!jl_isa(a, t))
     240                 :      14225 :                 return 0;
     241                 :            :         }
     242                 :  762199000 :         return 1;
     243                 :            :     }
     244                 :  498898000 :     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                 :   33910500 : static int is_cache_leaf(jl_value_t *ty, int tparam)
     256                 :            : {
     257         [ +  + ]:   33910500 :     if (ty == jl_bottom_type)
     258                 :       9672 :         return 1;
     259   [ +  +  +  +  :   33900800 :     return (jl_is_concrete_type(ty) && (tparam || !jl_is_kind(ty)));
                   +  + ]
     260                 :            : }
     261                 :            : 
     262                 :     521207 : static _Atomic(jl_typemap_t*) *mtcache_hash_lookup_bp(jl_array_t *cache JL_PROPAGATES_ROOT, jl_value_t *ty) JL_NOTSAFEPOINT
     263                 :            : {
     264         [ +  + ]:     521207 :     if (cache == (jl_array_t*)jl_an_empty_vec_any)
     265                 :       4935 :         return NULL;
     266                 :     516272 :     _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                 :     516272 :     return pml;
     269                 :            : }
     270                 :            : 
     271                 :     183123 : static void mtcache_hash_insert(_Atomic(jl_array_t*) *cache, jl_value_t *parent, jl_value_t *key, jl_typemap_t *val)
     272                 :            : {
     273                 :     183123 :     int inserted = 0;
     274                 :     183123 :     jl_array_t *a = jl_atomic_load_relaxed(cache);
     275         [ +  + ]:     183123 :     if (a == (jl_array_t*)jl_an_empty_vec_any) {
     276                 :       4935 :         a = jl_alloc_vec_any(16);
     277                 :       4935 :         jl_atomic_store_release(cache, a);
     278                 :       4935 :         jl_gc_wb(parent, a);
     279                 :            :     }
     280                 :     183123 :     a = jl_eqtable_put(a, key, val, &inserted);
     281         [ -  + ]:     183123 :     assert(inserted);
     282         [ +  + ]:     183123 :     if (a != jl_atomic_load_relaxed(cache)) {
     283                 :       5377 :         jl_atomic_store_release(cache, a);
     284                 :       5377 :         jl_gc_wb(parent, a);
     285                 :            :     }
     286                 :     183123 : }
     287                 :            : 
     288                 :   51217500 : static jl_typemap_t *mtcache_hash_lookup(jl_array_t *cache JL_PROPAGATES_ROOT, jl_value_t *ty) JL_NOTSAFEPOINT
     289                 :            : {
     290         [ -  + ]:   51217500 :     if (cache == (jl_array_t*)jl_an_empty_vec_any)
     291                 :          0 :         return (jl_typemap_t*)jl_nothing;
     292                 :   51217500 :     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                 :   51217500 :     return ml;
     295                 :            : }
     296                 :            : 
     297                 :            : // ----- Sorted Type Signature Lookup Matching ----- //
     298                 :            : 
     299                 :      71915 : static int jl_typemap_array_visitor(jl_array_t *a, jl_typemap_visitor_fptr fptr, void *closure)
     300                 :            : {
     301                 :      71915 :     size_t i, l = jl_array_len(a);
     302                 :      71915 :     _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_data(a);
     303         [ +  + ]:    4544270 :     for (i = 1; i < l; i += 2) {
     304                 :    4472360 :         jl_value_t *d = jl_atomic_load_relaxed(&data[i]);
     305                 :            :         JL_GC_PROMISE_ROOTED(d);
     306   [ +  +  +  + ]:    4472360 :         if (d && !jl_typemap_visitor(d, fptr, closure))
     307                 :          4 :             return 0;
     308                 :            :     }
     309                 :      71911 :     return 1;
     310                 :            : }
     311                 :            : 
     312                 :            : 
     313                 :            : // calls fptr on each jl_typemap_entry_t in cache in sort order, until fptr return false
     314                 :    2571240 : static int jl_typemap_node_visitor(jl_typemap_entry_t *ml, jl_typemap_visitor_fptr fptr, void *closure)
     315                 :            : {
     316         [ +  + ]:    6628220 :     while (ml != (void*)jl_nothing) {
     317         [ +  + ]:    4056990 :         if (!fptr(ml, closure))
     318                 :         18 :             return 0;
     319                 :    4056970 :         ml = jl_atomic_load_relaxed(&ml->next);
     320                 :            :     }
     321                 :    2571230 :     return 1;
     322                 :            : }
     323                 :            : 
     324                 :    2571250 : int jl_typemap_visitor(jl_typemap_t *cache, jl_typemap_visitor_fptr fptr, void *closure)
     325                 :            : {
     326         [ +  + ]:    2571250 :     if (jl_typeof(cache) == (jl_value_t*)jl_typemap_level_type) {
     327                 :      51907 :         jl_typemap_level_t *node = (jl_typemap_level_t*)cache;
     328                 :            :         jl_array_t *a;
     329                 :      51907 :         JL_GC_PUSH1(&a);
     330                 :      51907 :         a = jl_atomic_load_relaxed(&node->targ);
     331         [ +  + ]:      51907 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     332         [ +  + ]:       4254 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     333                 :          4 :                 goto exit;
     334                 :      51906 :         a = jl_atomic_load_relaxed(&node->arg1);
     335         [ +  + ]:      51906 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     336         [ +  + ]:      41724 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     337                 :          3 :                 goto exit;
     338                 :      51903 :         a = jl_atomic_load_relaxed(&node->tname);
     339         [ +  + ]:      51903 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     340         [ -  + ]:       6308 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     341                 :          0 :                 goto exit;
     342                 :      51903 :         a = jl_atomic_load_relaxed(&node->name1);
     343         [ +  + ]:      51903 :         if (a != (jl_array_t*)jl_an_empty_vec_any)
     344         [ -  + ]:      19629 :             if (!jl_typemap_array_visitor(a, fptr, closure))
     345                 :          0 :                 goto exit;
     346         [ -  + ]:      51903 :         if (!jl_typemap_node_visitor(jl_atomic_load_relaxed(&node->linear), fptr, closure))
     347                 :          0 :             goto exit;
     348         [ -  + ]:      51903 :         if (!jl_typemap_visitor(jl_atomic_load_relaxed(&node->any), fptr, closure))
     349                 :          0 :             goto exit;
     350                 :      51903 :         JL_GC_POP();
     351                 :      51903 :         return 1;
     352                 :            :     }
     353                 :            :     else {
     354                 :    2519340 :         return jl_typemap_node_visitor((jl_typemap_entry_t*)cache, fptr, closure);
     355                 :            :     }
     356                 :            : 
     357                 :          4 : exit:
     358                 :          4 :     JL_GC_POP();
     359                 :          4 :     return 0;
     360                 :            : }
     361                 :            : 
     362                 :     755412 : static unsigned jl_supertype_height(jl_datatype_t *dt)
     363                 :            : {
     364                 :     755412 :     unsigned height = 1;
     365         [ +  + ]:    1311680 :     while (dt != jl_any_type) {
     366                 :     556269 :         height++;
     367                 :     556269 :         dt = dt->super;
     368                 :            :     }
     369                 :     755412 :     return height;
     370                 :            : }
     371                 :            : 
     372                 :            : // return true if a and b might intersect in the type domain (over just their type-names)
     373                 :    2244020 : static int tname_intersection(jl_datatype_t *a, jl_typename_t *bname, unsigned ha)
     374                 :            : {
     375                 :    2244020 :     jl_datatype_t *b = (jl_datatype_t*)jl_unwrap_unionall(bname->wrapper);
     376                 :    2244020 :     unsigned hb = 1;
     377         [ +  + ]:    5416880 :     while (b != jl_any_type) {
     378         [ +  + ]:    4105290 :         if (a->name == b->name)
     379                 :     932437 :             return 1;
     380                 :    3172860 :         hb++;
     381                 :    3172860 :         b = b->super;
     382                 :            :     }
     383         [ +  + ]:    1564950 :     while (ha > hb) {
     384                 :     253362 :         a = a->super;
     385                 :     253362 :         ha--;
     386                 :            :     }
     387                 :    1311590 :     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                 :    1484360 : 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                 :    1484360 :     JL_GC_PUSH1(&a);
     396                 :    1484360 :     size_t i, l = jl_array_len(a);
     397                 :    1484360 :     _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_data(a);
     398         [ +  + ]:    1484360 :     unsigned height = tparam & 2 ? jl_supertype_height((jl_datatype_t*)ty) : 0;
     399         [ +  + ]:  189436000 :     for (i = 0; i < l; i += 2) {
     400                 :  188034000 :         jl_value_t *t = jl_atomic_load_relaxed(&data[i]);
     401                 :            :         JL_GC_PROMISE_ROOTED(t);
     402   [ +  -  +  + ]:  188034000 :         if (t == jl_nothing || t == NULL)
     403                 :  141020000 :             continue;
     404         [ +  + ]:   47013400 :         if (tparam & 2) {
     405                 :    7051420 :             jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i + 1]);
     406                 :            :             JL_GC_PROMISE_ROOTED(ml);
     407   [ +  +  +  + ]:    9295440 :             if (ty == (jl_value_t*)jl_any_type || // easy case: Any always matches
     408                 :    2244020 :                 tname_intersection((jl_datatype_t*)ty, (jl_typename_t*)t, height)) {
     409         [ +  + ]:    5750420 :                 if (!jl_typemap_intersection_visitor(ml, offs + 1, closure))
     410                 :        224 :                     goto exit;
     411                 :            :             }
     412                 :            :         }
     413                 :            :         else {
     414                 :            :             // `t` is a leaftype, so intersection test becomes subtype
     415   [ +  +  +  +  :   77993200 :             if (ty == (jl_value_t*)jl_any_type || // easy case: Any always matches
                   +  + ]
     416         [ +  + ]:   38031300 :                 (tparam & 1
     417   [ +  +  +  + ]:   29603900 :                  ? (jl_typeof(t) == ty || jl_isa(t, ty)) // (Type{t} <: ty), where is_leaf_type(t) => isa(t, ty)
     418   [ +  -  +  + ]:    8427360 :                  : (t == ty || jl_subtype(t, ty)))) {
     419                 :    5324870 :                 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   [ +  -  +  + ]:    5324870 :                 if (ml != NULL && !jl_typemap_intersection_visitor(ml, offs + 1, closure))
     423                 :      81213 :                     goto exit;
     424                 :            :             }
     425                 :            :         }
     426                 :            :     }
     427                 :    1402920 :     JL_GC_POP();
     428                 :    1402920 :     return 1;
     429                 :            : 
     430                 :      81437 : exit:
     431                 :      81437 :     JL_GC_POP();
     432                 :      81437 :     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                 :   22301000 : 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                 :   22301000 :     register jl_typemap_intersection_visitor_fptr fptr = closure->fptr;
     443         [ +  + ]:   73003400 :     while (ml != (void*)jl_nothing) {
     444         [ +  + ]:   50790000 :         if (closure->type == (jl_value_t*)ml->sig) {
     445                 :            :             // fast-path for the intersection of a type with itself
     446         [ +  - ]:     131126 :             if (closure->env)
     447                 :     131126 :                 closure->env = jl_outer_unionall_vars((jl_value_t*)ml->sig);
     448                 :     131126 :             closure->ti = closure->type;
     449                 :     131126 :             closure->issubty = 1;
     450         [ -  + ]:     131126 :             if (!fptr(ml, closure))
     451                 :          0 :                 return 0;
     452                 :            :         }
     453                 :            :         else {
     454                 :   50658900 :             jl_svec_t **penv = NULL;
     455         [ +  - ]:   50658900 :             if (closure->env) {
     456                 :   50658900 :                 closure->env = jl_emptysvec;
     457                 :   50658900 :                 penv = &closure->env;
     458                 :            :             }
     459                 :   50658900 :             closure->ti = jl_type_intersection_env_s(closure->type, (jl_value_t*)ml->sig, penv, &closure->issubty);
     460         [ +  + ]:   50658900 :             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   [ +  +  +  + ]:   10034900 :                 if (closure->issubty || !jl_is_dispatch_tupletype(closure->type))
     466         [ +  + ]:   10033600 :                     if (!fptr(ml, closure))
     467                 :      87603 :                         return 0;
     468                 :            :             }
     469                 :            :         }
     470                 :   50702400 :         ml = jl_atomic_load_relaxed(&ml->next);
     471                 :            :     }
     472                 :   22213400 :     return 1;
     473                 :            : }
     474                 :            : 
     475                 :   22460500 : int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
     476                 :            :                                     struct typemap_intersection_env *closure)
     477                 :            : {
     478                 :   22460500 :     jl_value_t *ttypes = jl_unwrap_unionall(closure->type);
     479         [ -  + ]:   22460500 :     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         [ +  + ]:   22460500 :     if (jl_typeof(map) == (jl_value_t *)jl_typemap_level_type) {
     494                 :    3570690 :         jl_typemap_level_t *cache = (jl_typemap_level_t*)map;
     495                 :            :         jl_value_t *ty;
     496                 :    3570690 :         size_t l = jl_nparams(ttypes);
     497   [ +  +  +  + ]:    3570690 :         if (closure->va && l <= offs + 1) {
     498                 :       2745 :             ty = closure->va;
     499                 :            :         }
     500         [ +  + ]:    3567940 :         else if (l > offs) {
     501                 :    3559060 :             ty = jl_tparam(ttypes, offs);
     502                 :            :         }
     503                 :            :         else {
     504                 :       8879 :             ty = NULL;
     505                 :            :         }
     506         [ +  + ]:    3570690 :         if (ty == (jl_value_t*)jl_typeofbottom_type)
     507                 :        101 :             ty = (jl_value_t*)jl_assume(jl_typeofbottom_type)->super;
     508         [ +  + ]:    3570690 :         if (ty) {
     509         [ +  + ]:    3563650 :             while (jl_is_typevar(ty))
     510                 :       1844 :                 ty = ((jl_tvar_t*)ty)->ub;
     511                 :    3561810 :             jl_value_t *typetype = jl_unwrap_unionall(ty);
     512         [ +  + ]:    3561810 :             typetype = jl_is_type_type(typetype) ? jl_tparam0(typetype) : NULL;
     513                 :            :             // approxify the tparam until we have a valid type
     514         [ +  + ]:    3561810 :             if (jl_has_free_typevars(ty)) {
     515                 :      16748 :                 ty = jl_unwrap_unionall(ty);
     516         [ +  + ]:      16748 :                 if (jl_is_datatype(ty))
     517                 :      16136 :                     ty = ((jl_datatype_t*)ty)->name->wrapper;
     518                 :            :                 else
     519                 :        612 :                     ty = (jl_value_t*)jl_any_type;
     520                 :            :             }
     521                 :    3561810 :             jl_array_t *targ = jl_atomic_load_relaxed(&cache->targ);
     522         [ +  + ]:    3561810 :             if (targ != (jl_array_t*)jl_an_empty_vec_any) {
     523   [ +  +  +  + ]:     712621 :                 if (typetype && !jl_has_free_typevars(typetype)) {
     524         [ +  + ]:     563968 :                     if (is_cache_leaf(typetype, 1)) {
     525                 :            :                         // direct lookup of leaf types
     526                 :     352806 :                         jl_typemap_t *ml = mtcache_hash_lookup(targ, typetype);
     527         [ +  + ]:     352806 :                         if (ml != jl_nothing) {
     528         [ +  + ]:     104546 :                             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   [ +  +  +  + ]:     148653 :                     if (typetype || !jl_has_empty_intersection((jl_value_t*)jl_type_type, ty)) {
     536                 :     104316 :                         targ = jl_atomic_load_relaxed(&cache->targ); // may be GC'd during type-intersection
     537         [ +  + ]:     104316 :                         if (!jl_typemap_intersection_array_visitor(targ, ty, 1, offs, closure)) return 0;
     538                 :            :                     }
     539                 :            :                 }
     540                 :            :             }
     541                 :    3544830 :             jl_array_t *cachearg1 = jl_atomic_load_relaxed(&cache->arg1);
     542         [ +  + ]:    3544830 :             if (cachearg1 != (jl_array_t*)jl_an_empty_vec_any) {
     543         [ +  + ]:    2549250 :                 if (is_cache_leaf(ty, 0)) {
     544                 :            :                     // direct lookup of leaf types
     545                 :    1924620 :                     jl_typemap_t *ml = mtcache_hash_lookup(cachearg1, ty);
     546         [ +  + ]:    1924620 :                     if (ml != jl_nothing) {
     547         [ +  + ]:    1435440 :                         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         [ +  + ]:     624630 :                     if (!jl_typemap_intersection_array_visitor(cachearg1, ty, 0, offs, closure)) return 0;
     553                 :            :                 }
     554                 :            :             }
     555                 :    3402680 :             jl_array_t *tname = jl_atomic_load_relaxed(&cache->tname);
     556         [ +  + ]:    3402680 :             if (tname != (jl_array_t*)jl_an_empty_vec_any) {
     557         [ +  + ]:    1126620 :                 jl_value_t *name = typetype ? jl_type_extract_name(typetype) : NULL;
     558   [ +  +  +  + ]:    1738230 :                 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                 :     611811 :                     jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
     565         [ +  - ]:     611811 :                     if (jl_type_extract_name_precise(typetype, 1)) {
     566                 :            :                         // just consider the type and its direct super types
     567                 :    1130840 :                         while (1) {
     568                 :    1742650 :                             tname = jl_atomic_load_relaxed(&cache->tname); // reload after callback
     569                 :    1742650 :                             jl_typemap_t *ml = mtcache_hash_lookup(tname, (jl_value_t*)super->name);
     570         [ +  + ]:    1742650 :                             if (ml != jl_nothing) {
     571         [ +  + ]:    1151250 :                                 if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0;
     572                 :            :                             }
     573         [ +  + ]:    1742450 :                             if (super == jl_any_type)
     574                 :     611607 :                                 break;
     575                 :    1130840 :                             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   [ +  +  +  + ]:     514808 :                     if (name || !jl_has_empty_intersection((jl_value_t*)jl_type_type, ty)) {
     587                 :      99929 :                         tname = jl_atomic_load_relaxed(&cache->tname);  // may be GC'd during type-intersection
     588         [ +  + ]:      99929 :                         if (!jl_typemap_intersection_array_visitor(tname, (jl_value_t*)jl_any_type, 3, offs, closure)) return 0;
     589                 :            :                     }
     590                 :            :                 }
     591                 :            :             }
     592                 :    3402250 :             jl_array_t *name1 = jl_atomic_load_relaxed(&cache->name1);
     593         [ +  + ]:    3402250 :             if (name1 != (jl_array_t*)jl_an_empty_vec_any) {
     594                 :    1880230 :                 jl_value_t *name = jl_type_extract_name(ty);
     595         [ +  + ]:    1880230 :                 if (name) {
     596                 :    1840530 :                     jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
     597         [ +  + ]:    1840530 :                     if (jl_type_extract_name_precise(ty, 0)) {
     598                 :            :                         // direct lookup of concrete types
     599                 :    2631350 :                         while (1) {
     600                 :    3856100 :                             name1 = jl_atomic_load_relaxed(&cache->name1); // reload after callback
     601                 :    3856100 :                             jl_typemap_t *ml = mtcache_hash_lookup(name1, (jl_value_t*)super->name);
     602         [ +  + ]:    3856100 :                             if (ml != jl_nothing) {
     603         [ -  + ]:    1321880 :                                 if (!jl_typemap_intersection_visitor(ml, offs+1, closure)) return 0;
     604                 :            :                             }
     605         [ +  + ]:    3856100 :                             if (super == jl_any_type)
     606                 :    1224750 :                                 break;
     607                 :    2631350 :                             super = super->super;
     608                 :            :                         }
     609                 :            :                     }
     610                 :            :                     else {
     611                 :            :                         // consider all of the possible subtypes too
     612         [ -  + ]:     615781 :                         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         [ -  + ]:      39702 :                     if (!jl_typemap_intersection_array_visitor(name1, (jl_value_t*)jl_any_type, 2, offs, closure)) return 0;
     618                 :            :                 }
     619                 :            :             }
     620                 :            :         }
     621         [ +  + ]:    3411130 :         if (!jl_typemap_intersection_node_visitor(jl_atomic_load_relaxed(&cache->linear), closure))
     622                 :         28 :             return 0;
     623                 :    3411100 :         return jl_typemap_intersection_visitor(jl_atomic_load_relaxed(&cache->any), offs+1, closure);
     624                 :            :     }
     625                 :            :     else {
     626                 :   18889800 :         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                 :   10447200 : 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                 :   10447200 :     jl_value_t *types = search->types;
     647                 :            :     JL_GC_PROMISE_ROOTED(types);
     648                 :   10447200 :     jl_value_t *unw = jl_unwrap_unionall((jl_value_t*)types);
     649                 :   10447200 :     int isua = jl_is_unionall(types);
     650                 :   10447200 :     size_t n = jl_nparams(unw);
     651         [ +  - ]:   10447200 :     int typesisva = n == 0 ? 0 : jl_is_vararg(jl_tparam(unw, n-1));
     652         [ +  + ]:   17825800 :     for (; ml != (void*)jl_nothing; ml = jl_atomic_load_relaxed(&ml->next)) {
     653                 :    9673480 :         size_t lensig = jl_nparams(jl_unwrap_unionall((jl_value_t*)ml->sig));
     654   [ +  +  +  +  :    9673480 :         if (lensig == n || (ml->va && lensig <= n+1)) {
                   +  + ]
     655                 :    8151760 :             int resetenv = 0, ismatch = 1;
     656   [ +  +  +  - ]:    8151760 :             if (ml->simplesig != (void*)jl_nothing && !isua) {
     657                 :    7667190 :                 size_t lensimplesig = jl_nparams(ml->simplesig);
     658   [ +  -  +  + ]:    7667190 :                 int isva = lensimplesig > 0 && jl_is_vararg(jl_tparam(ml->simplesig, lensimplesig - 1));
     659   [ +  +  +  -  :    7667190 :                 if (lensig == n || (isva && lensimplesig <= n + 1))
                   +  - ]
     660                 :    7667190 :                     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         [ +  + ]:    8151760 :             if (ismatch == 0)
     667                 :            :                 ; // nothing
     668   [ +  +  +  -  :    4756420 :             else if (ml->isleafsig && !typesisva && !isua)
                   +  - ]
     669                 :        136 :                 ismatch = sig_match_by_type_leaf(jl_svec_data(((jl_datatype_t*)types)->parameters),
     670                 :            :                                                  ml->sig, lensig);
     671   [ +  +  +  +  :    4756290 :             else if (ml->issimplesig && !typesisva && !isua)
                   +  - ]
     672                 :    2502010 :                 ismatch = sig_match_by_type_simple(jl_svec_data(((jl_datatype_t*)types)->parameters), n,
     673                 :    2502010 :                                                    ml->sig, lensig, ml->va);
     674                 :            :             else {
     675         [ +  + ]:    2254280 :                 ismatch = jl_subtype_matching(types, (jl_value_t*)ml->sig, search->env ? &search->env : NULL);
     676   [ +  +  +  + ]:    2254280 :                 if (ismatch && search->env)
     677                 :    1293710 :                     resetenv = 1;
     678                 :            :             }
     679                 :            : 
     680         [ +  + ]:    8151760 :             if (ismatch) {
     681                 :            :                 size_t i, l;
     682         [ +  + ]:    2454970 :                 for (i = 0, l = jl_svec_len(ml->guardsigs); i < l; i++) {
     683                 :            :                     // see corresponding code in jl_typemap_entry_assoc_exact
     684         [ +  + ]:     158763 :                     if (jl_subtype(types, jl_svecref(ml->guardsigs, i))) {
     685                 :      10352 :                         ismatch = 0;
     686                 :      10352 :                         break;
     687                 :            :                     }
     688                 :            :                 }
     689         [ +  + ]:    2306560 :                 if (ismatch) {
     690         [ +  + ]:    2296200 :                     if (search->world < ml->min_world) {
     691                 :            :                         // ignore method table entries that are part of a later world
     692         [ +  - ]:          8 :                         if (search->max_valid >= ml->min_world)
     693                 :          8 :                             search->max_valid = ml->min_world - 1;
     694                 :            :                     }
     695         [ +  + ]:    2296200 :                     else if (search->world > ml->max_world) {
     696                 :            :                         // ignore method table entries that have been replaced in the current world
     697         [ +  - ]:       1335 :                         if (search->min_valid <= ml->max_world)
     698                 :       1335 :                             search->min_valid = ml->max_world + 1;
     699                 :            :                     }
     700                 :            :                     else {
     701                 :            :                         // intersect the env valid range with method's valid range
     702         [ +  + ]:    2294860 :                         if (search->min_valid < ml->min_world)
     703                 :    2294420 :                             search->min_valid = ml->min_world;
     704         [ -  + ]:    2294860 :                         if (search->max_valid > ml->max_world)
     705                 :          0 :                             search->max_valid = ml->max_world;
     706                 :    2294860 :                         return ml;
     707                 :            :                     }
     708                 :            :                 }
     709                 :            :             }
     710         [ +  + ]:    5856900 :             if (resetenv)
     711                 :       2452 :                 search->env = jl_emptysvec;
     712                 :            :         }
     713                 :            :     }
     714                 :    8152330 :     return NULL;
     715                 :            : }
     716                 :            : 
     717                 :     303558 : static jl_typemap_entry_t *jl_typemap_entry_lookup_by_type(
     718                 :            :         jl_typemap_entry_t *ml, struct jl_typemap_assoc *search)
     719                 :            : {
     720         [ +  + ]:    1178270 :     for (; ml != (void*)jl_nothing; ml = jl_atomic_load_relaxed(&ml->next)) {
     721   [ +  +  +  + ]:     891863 :         if (search->world < ml->min_world || search->world > ml->max_world)
     722                 :      11006 :             continue;
     723                 :            :         // unroll the first few cases here, to the extent that is possible to do fast and easily
     724                 :     880857 :         jl_value_t *types = search->types;
     725                 :            :         JL_GC_PROMISE_ROOTED(types);
     726                 :     880857 :         jl_value_t *a = jl_unwrap_unionall(types);
     727                 :     880857 :         jl_value_t *b = jl_unwrap_unionall((jl_value_t*)ml->sig);
     728                 :     880857 :         size_t na = jl_nparams(a);
     729                 :     880857 :         size_t nb = jl_nparams(b);
     730   [ +  -  +  + ]:     880857 :         int va_a = na > 0 && jl_is_vararg(jl_tparam(a, na - 1));
     731   [ +  -  +  + ]:     880857 :         int va_b = nb > 0 && jl_is_vararg(jl_tparam(b, nb - 1));
     732   [ +  +  +  + ]:     880857 :         if (!va_a && !va_b) {
     733         [ +  + ]:     834810 :             if (na != nb)
     734                 :     435156 :                 continue;
     735                 :            :         }
     736   [ +  -  +  - ]:     445701 :         if (na - va_a > 0 && nb - va_b > 0) {
     737         [ +  + ]:     445701 :             if (jl_obviously_unequal(jl_tparam(a, 0), jl_tparam(b, 0)))
     738                 :     193530 :                 continue;
     739   [ +  +  +  + ]:     252171 :             if (na - va_a > 1 && nb - va_b > 1) {
     740         [ +  + ]:     245263 :                 if (jl_obviously_unequal(jl_tparam(a, 1), jl_tparam(b, 1)))
     741                 :      79273 :                     continue;
     742   [ +  +  +  + ]:     165990 :                 if (na - va_a > 2 && nb - va_b > 2) {
     743         [ +  + ]:     138319 :                     if (jl_obviously_unequal(jl_tparam(a, 2), jl_tparam(b, 2)))
     744                 :      62578 :                         continue;
     745                 :            :                 }
     746                 :            :             }
     747                 :            :         }
     748         [ +  + ]:     110320 :         if (jl_types_equal(types, (jl_value_t*)ml->sig))
     749                 :      17150 :             return ml;
     750                 :            :     }
     751                 :     286408 :     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                 :   13166500 : 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         [ +  + ]:   13166500 :     if (jl_typeof(ml_or_cache) == (jl_value_t *)jl_typemap_level_type) {
     763                 :    4890440 :         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                 :    4890440 :         jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)search->types);
     767                 :            :         JL_GC_PROMISE_ROOTED(ttypes);
     768         [ -  + ]:    4890440 :         assert(jl_is_datatype(ttypes));
     769                 :    4890440 :         size_t l = jl_nparams(ttypes);
     770                 :    4890440 :         int isva = 0;
     771                 :            :         // compute the type at offset `offs` into `types`, which may be a Vararg
     772         [ +  + ]:    4890440 :         if (l <= offs + 1) {
     773                 :    1196030 :             ty = jl_tparam(ttypes, l - 1);
     774         [ +  + ]:    1196030 :             if (jl_is_vararg(ty)) {
     775                 :       2122 :                 ty = jl_unwrap_vararg(ty);
     776                 :       2122 :                 isva = 1;
     777                 :            :             }
     778         [ +  + ]:    1193910 :             else if (l <= offs) {
     779                 :     131173 :                 ty = NULL;
     780                 :            :             }
     781                 :            :         }
     782         [ +  + ]:    3694410 :         else if (l > offs) {
     783                 :    3694380 :             ty = jl_tparam(ttypes, offs);
     784                 :            :         }
     785                 :            :         else {
     786                 :         36 :             ty = NULL;
     787                 :            :         }
     788         [ +  + ]:    4890440 :         if (ty == (jl_value_t*)jl_typeofbottom_type)
     789                 :       2388 :             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   [ +  +  +  + ]:    4890440 :         if (ty && !subtype) {
     792         [ +  + ]:      64203 :             if (jl_is_any(ty))
     793                 :       9784 :                 return jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&cache->any), search, offs + 1, subtype);
     794         [ +  + ]:      54419 :             if (isva) // in lookup mode, want to match Vararg exactly, not as a subtype
     795                 :        181 :                 ty = NULL;
     796                 :            :         }
     797         [ +  + ]:    4880660 :         if (ty) {
     798                 :            :             // now look at the optimized leaftype caches
     799         [ +  + ]:    4749270 :             if (jl_is_type_type(ty)) {
     800                 :    1449080 :                 jl_value_t *a0 = jl_tparam0(ty);
     801         [ +  + ]:    1449080 :                 if (is_cache_leaf(a0, 1)) {
     802                 :     601438 :                     jl_array_t *targ = jl_atomic_load_relaxed(&cache->targ);
     803         [ +  + ]:     601438 :                     if (targ != (jl_array_t*)jl_an_empty_vec_any) {
     804                 :     537591 :                         jl_typemap_t *ml = mtcache_hash_lookup(targ, a0);
     805         [ +  + ]:     537591 :                         if (ml != jl_nothing) {
     806                 :     212373 :                             jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     807         [ +  + ]:     212373 :                             if (li) return li;
     808                 :            :                         }
     809                 :            :                     }
     810         [ +  + ]:     432237 :                     if (!subtype) return NULL;
     811                 :            :                 }
     812                 :            :             }
     813         [ +  + ]:    4576310 :             if (is_cache_leaf(ty, 0)) {
     814                 :    3186340 :                 jl_array_t *cachearg1 = jl_atomic_load_relaxed(&cache->arg1);
     815         [ +  + ]:    3186340 :                 if (cachearg1 != (jl_array_t*)jl_an_empty_vec_any) {
     816                 :    2954190 :                     jl_typemap_t *ml = mtcache_hash_lookup(cachearg1, ty);
     817         [ +  + ]:    2954190 :                     if (ml != jl_nothing) {
     818                 :    1477950 :                         jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     819         [ +  + ]:    1477950 :                         if (li) return li;
     820                 :            :                     }
     821                 :            :                 }
     822         [ +  + ]:    2374910 :                 if (!subtype) return NULL;
     823                 :            :             }
     824                 :            :         }
     825   [ +  +  +  + ]:    3879550 :         if (ty || subtype) {
     826                 :            :             // now look at the optimized TypeName caches
     827                 :    3876550 :             jl_array_t *tname = jl_atomic_load_relaxed(&cache->tname);
     828         [ +  + ]:    3876550 :             if (tname != (jl_array_t*)jl_an_empty_vec_any) {
     829   [ +  +  +  + ]:    2454290 :                 jl_value_t *a0 = ty && jl_is_type_type(ty) ? jl_type_extract_name(jl_tparam0(ty)) : NULL;
     830         [ +  + ]:    2454290 :                 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                 :    1231460 :                     jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper);
     832                 :    1454930 :                     while (1) {
     833                 :    2686390 :                         tname = jl_atomic_load_relaxed(&cache->tname); // reload after tree descent (which may hit safepoints)
     834                 :    2686390 :                         jl_typemap_t *ml = mtcache_hash_lookup(tname, (jl_value_t*)super->name);
     835         [ +  + ]:    2686390 :                         if (ml != (void*)jl_nothing) {
     836                 :    1737700 :                             jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     837         [ +  + ]:    2558790 :                             if (li) return li;
     838                 :            :                         }
     839   [ +  +  +  + ]:    2102580 :                         if (super == jl_any_type || !subtype)
     840                 :            :                             break;
     841                 :    1454930 :                         super = super->super;
     842                 :            :                     }
     843                 :            :                 }
     844                 :            :                 else {
     845   [ +  +  +  + ]:    1222830 :                     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                 :      31652 :                         size_t i, l = jl_array_len(tname);
     848                 :      31652 :                         _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_ptr_data(tname);
     849                 :      31652 :                         JL_GC_PUSH1(&tname);
     850         [ +  + ]:     906913 :                         for (i = 1; i < l; i += 2) {
     851                 :     892068 :                             jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i]);
     852   [ +  +  -  + ]:     892068 :                             if (ml == NULL || ml == jl_nothing)
     853                 :     524346 :                                 continue;
     854                 :     367722 :                             jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     855         [ +  + ]:     367722 :                             if (li) {
     856                 :      16807 :                                 JL_GC_POP();
     857                 :      16807 :                                 return li;
     858                 :            :                             }
     859                 :            :                         }
     860                 :      14845 :                         JL_GC_POP();
     861                 :            :                     }
     862                 :            :                 }
     863                 :            :             }
     864                 :    3275930 :             jl_array_t *name1 = jl_atomic_load_relaxed(&cache->name1);
     865         [ +  + ]:    3275930 :             if (name1 != (jl_array_t*)jl_an_empty_vec_any) {
     866         [ +  + ]:    1210080 :                 if (ty) {
     867                 :    1208470 :                     jl_value_t *a0 = jl_type_extract_name(ty);
     868         [ +  + ]:    1208470 :                     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                 :    1206460 :                         jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper);
     870                 :     889493 :                         while (1) {
     871                 :    2095960 :                             name1 = jl_atomic_load_relaxed(&cache->name1); // reload after tree descent (which may hit safepoints)
     872                 :    2095960 :                             jl_typemap_t *ml = mtcache_hash_lookup(name1, (jl_value_t*)super->name);
     873         [ +  + ]:    2095960 :                             if (ml != (void*)jl_nothing) {
     874                 :            :                                 jl_typemap_entry_t *li =
     875                 :    1053270 :                                     jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     876         [ +  + ]:    1053270 :                                 if (li) return li;
     877                 :            :                             }
     878   [ +  +  +  + ]:    1291670 :                             if (super == jl_any_type || !subtype)
     879                 :            :                                 break;
     880                 :     889493 :                             super = super->super;
     881                 :            :                         }
     882                 :            :                     }
     883                 :            :                 }
     884                 :            :                 else {
     885                 :            :                     // doing subtype, but couldn't figure out unique `ty`, so scan all for supertypes
     886                 :       1608 :                     size_t i, l = jl_array_len(name1);
     887                 :       1608 :                     _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_ptr_data(name1);
     888                 :       1608 :                     JL_GC_PUSH1(&name1);
     889         [ +  + ]:      14480 :                     for (i = 1; i < l; i += 2) {
     890                 :      12872 :                         jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i]);
     891   [ +  +  -  + ]:      12872 :                         if (ml == NULL || ml == jl_nothing)
     892                 :      11252 :                             continue;
     893                 :       1620 :                         jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, search, offs + 1, subtype);
     894         [ -  + ]:       1620 :                         if (li) {
     895                 :          0 :                             JL_GC_POP();
     896                 :          0 :                             return li;
     897                 :            :                         }
     898                 :            :                     }
     899                 :       1608 :                     JL_GC_POP();
     900                 :            :                 }
     901                 :            :             }
     902                 :            :         }
     903                 :            :         // Always check the list (since offs doesn't always start at 0)
     904         [ +  + ]:    2474640 :         if (subtype) {
     905                 :    2451740 :             jl_typemap_entry_t *li = jl_typemap_entry_assoc_by_type(jl_atomic_load_relaxed(&cache->linear), search);
     906         [ +  + ]:    2451740 :             if (li) return li;
     907                 :    2359500 :             return jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&cache->any), search, offs + 1, subtype);
     908                 :            :         }
     909                 :            :         else {
     910                 :      22907 :             return jl_typemap_entry_lookup_by_type(jl_atomic_load_relaxed(&cache->linear), search);
     911                 :            :         }
     912                 :            :     }
     913                 :            :     else {
     914                 :    8276100 :         jl_typemap_entry_t *leaf = (jl_typemap_entry_t*)ml_or_cache;
     915                 :            :         return subtype ?
     916         [ +  + ]:    8556750 :             jl_typemap_entry_assoc_by_type(leaf, search) :
     917                 :     280651 :             jl_typemap_entry_lookup_by_type(leaf, search);
     918                 :            :     }
     919                 :            : }
     920                 :            : 
     921                 : 1187930000 : 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   [ +  +  +  +  : 1187930000 :     while (ml->simplesig == (void*)jl_nothing && ml->guardsigs == jl_emptysvec && ml->isleafsig) {
                   +  + ]
     925                 :            :         // use a tight loop for as long as possible
     926   [ +  -  +  - ]:       3109 :         if (world >= ml->min_world && world <= ml->max_world) {
     927   [ +  +  +  - ]:       3109 :             if (n == jl_nparams(ml->sig) && jl_typeof(arg1) == jl_tparam(ml->sig, 0)) {
     928         [ -  + ]:       3103 :                 if (n == 1)
     929                 :          0 :                     return ml;
     930         [ +  + ]:       3103 :                 if (n == 2) {
     931         [ +  + ]:        113 :                     if (jl_typeof(args[0]) == jl_tparam(ml->sig, 1))
     932                 :         53 :                         return ml;
     933                 :            :                 }
     934         [ +  + ]:       2990 :                 else if (n == 3) {
     935   [ +  +  +  - ]:       2526 :                     if (jl_typeof(args[0]) == jl_tparam(ml->sig, 1) &&
     936                 :       1165 :                         jl_typeof(args[1]) == jl_tparam(ml->sig, 2))
     937                 :       1172 :                         return ml;
     938                 :            :                 }
     939                 :            :                 else {
     940         [ +  + ]:       1636 :                     if (sig_match_leaf(arg1, args, jl_svec_data(ml->sig->parameters), n))
     941                 :       1590 :                         return ml;
     942                 :            :                 }
     943                 :            :             }
     944                 :            :         }
     945                 :        301 :         ml = jl_atomic_load_relaxed(&ml->next);
     946         [ +  + ]:        301 :         if (ml == (void*)jl_nothing)
     947                 :         60 :             return NULL;
     948                 :            :     }
     949                 :            : 
     950         [ +  + ]: 1558500000 :     for (; ml != (void*)jl_nothing; ml = jl_atomic_load_relaxed(&ml->next)) {
     951   [ +  +  +  + ]: 1543360000 :         if (world < ml->min_world || world > ml->max_world)
     952                 :      18765 :             continue; // ignore replaced methods
     953                 : 1543340000 :         size_t lensig = jl_nparams(ml->sig);
     954   [ +  +  +  +  : 1543340000 :         if (lensig == n || (ml->va && lensig <= n+1)) {
                   +  + ]
     955         [ +  + ]: 1330860000 :             if (ml->simplesig != (void*)jl_nothing) {
     956                 :  430030000 :                 size_t lensimplesig = jl_nparams(ml->simplesig);
     957   [ +  #  +  + ]:  430030000 :                 int isva = lensimplesig > 0 && jl_is_vararg(jl_tparam(ml->simplesig, lensimplesig - 1));
     958   [ +  +  +  -  :  430030000 :                 if (lensig == n || (isva && lensimplesig <= n + 1)) {
                   +  - ]
     959         [ +  + ]:  430030000 :                     if (!sig_match_simple(arg1, args, n, jl_svec_data(ml->simplesig->parameters), isva, lensimplesig))
     960                 :   68929900 :                         continue;
     961                 :            :                 }
     962                 :            :                 else {
     963                 :          0 :                     continue;
     964                 :            :                 }
     965                 :            :             }
     966                 :            : 
     967         [ -  + ]: 1261930000 :             if (ml->isleafsig) {
     968         [ #  # ]:          0 :                 if (!sig_match_leaf(arg1, args, jl_svec_data(ml->sig->parameters), n))
     969                 :          0 :                     continue;
     970                 :            :             }
     971         [ +  + ]: 1261930000 :             else if (ml->issimplesig) {
     972         [ +  + ]:  981840000 :                 if (!sig_match_simple(arg1, args, n, jl_svec_data(ml->sig->parameters), ml->va, lensig))
     973                 :   81842400 :                     continue;
     974                 :            :             }
     975                 :            :             else {
     976         [ +  + ]:  280086000 :                 if (!jl_tuple1_isa(arg1, args, n, ml->sig))
     977                 :    6998200 :                     continue;
     978                 :            :             }
     979                 :            : 
     980                 :            :             size_t i, l;
     981         [ +  + ]: 1173090000 :             if (ml->guardsigs != jl_emptysvec) {
     982         [ +  + ]:   38869800 :                 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         [ +  + ]:   33010600 :                     if (jl_tuple1_isa(arg1, args, n, (jl_tupletype_t*)jl_svecref(ml->guardsigs, i))) {
     987                 :     303546 :                         goto nomatch;
     988                 :            :                     }
     989                 :            :                 }
     990                 :            :             }
     991                 : 1172780000 :             return ml;
     992                 :     303546 : nomatch:
     993                 :     303546 :             continue;
     994                 :            :         }
     995                 :            :     }
     996                 :   15146700 :     return NULL;
     997                 :            : }
     998                 :            : 
     999                 :   31072900 : 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         [ +  + ]:   31072900 :     if (n > offs) {
    1002         [ +  + ]:   30768200 :         jl_value_t *a1 = (offs == 0 ? arg1 : args[offs - 1]);
    1003                 :   30768200 :         jl_value_t *ty = jl_typeof(a1);
    1004         [ -  + ]:   30768200 :         assert(jl_is_datatype(ty));
    1005                 :   30768200 :         jl_array_t *targ = jl_atomic_load_relaxed(&cache->targ);
    1006   [ +  +  +  +  :   30768200 :         if (ty == (jl_value_t*)jl_datatype_type && targ != (jl_array_t*)jl_an_empty_vec_any && is_cache_leaf(a1, 1)) {
                   +  + ]
    1007                 :    5818520 :             jl_typemap_t *ml_or_cache = mtcache_hash_lookup(targ, a1);
    1008                 :    5818520 :             jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1009         [ +  + ]:   30510800 :             if (ml) return ml;
    1010                 :            :         }
    1011                 :   25373500 :         jl_array_t *cachearg1 = jl_atomic_load_relaxed(&cache->arg1);
    1012   [ +  +  +  + ]:   25373500 :         if (cachearg1 != (jl_array_t*)jl_an_empty_vec_any && is_cache_leaf(ty, 0)) {
    1013                 :   15871800 :             jl_typemap_t *ml_or_cache = mtcache_hash_lookup(cachearg1, ty);
    1014                 :   15871800 :             jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1015         [ +  + ]:   15871800 :             if (ml) return ml;
    1016                 :            :         }
    1017                 :   11549700 :         jl_array_t *tname = jl_atomic_load_relaxed(&cache->tname);
    1018   [ +  +  +  + ]:   11549700 :         if (jl_is_kind(ty) && tname != (jl_array_t*)jl_an_empty_vec_any) {
    1019                 :    9269600 :             jl_value_t *name = jl_type_extract_name(a1);
    1020         [ +  + ]:    9269600 :             if (name) {
    1021         [ +  + ]:    8664790 :                 if (ty != (jl_value_t*)jl_datatype_type)
    1022                 :    5674200 :                     a1 = jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
    1023                 :    2477130 :                 while (1) {
    1024                 :   11141900 :                     tname = jl_atomic_load_relaxed(&cache->tname); // reload after tree descent (which may hit safepoints)
    1025                 :   11141900 :                     jl_typemap_t *ml_or_cache = mtcache_hash_lookup(
    1026                 :   11141900 :                             tname, (jl_value_t*)((jl_datatype_t*)a1)->name);
    1027                 :   11141900 :                     jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1028         [ +  + ]:   11141900 :                     if (ml) return ml;
    1029         [ +  + ]:    2497650 :                     if (a1 == (jl_value_t*)jl_any_type)
    1030                 :      20514 :                         break;
    1031                 :    2477130 :                     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                 :     604816 :                 size_t i, l = jl_array_len(tname);
    1037                 :     604816 :                 _Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*)jl_array_ptr_data(tname);
    1038                 :     604816 :                 JL_GC_PUSH1(&tname);
    1039         [ +  + ]:    4321860 :                 for (i = 1; i < l; i += 2) {
    1040                 :    4319630 :                     jl_typemap_t *ml_or_cache = jl_atomic_load_relaxed(&data[i]);
    1041   [ +  +  -  + ]:    4319630 :                     if (ml_or_cache == NULL || ml_or_cache == jl_nothing)
    1042                 :    2976440 :                         continue;
    1043                 :    1343190 :                     jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs + 1, world);
    1044         [ +  + ]:    1343190 :                     if (ml) {
    1045                 :     602594 :                         JL_GC_POP();
    1046                 :     602594 :                         return ml;
    1047                 :            :                     }
    1048                 :            :                 }
    1049                 :       2222 :                 JL_GC_POP();
    1050                 :            :             }
    1051                 :            :         }
    1052                 :    2302840 :         jl_array_t *name1 = jl_atomic_load_relaxed(&cache->name1);
    1053         [ +  + ]:    2302840 :         if (name1 != (jl_array_t*)jl_an_empty_vec_any) {
    1054                 :     575476 :             while (1) {
    1055                 :    2234930 :                 name1 = jl_atomic_load_relaxed(&cache->name1); // reload after tree descent (which may hit safepoints)
    1056                 :    2234930 :                 jl_typemap_t *ml_or_cache = mtcache_hash_lookup(
    1057                 :    2234930 :                         name1, (jl_value_t*)((jl_datatype_t*)ty)->name);
    1058                 :    2234940 :                 jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, arg1, args, n, offs+1, world);
    1059         [ +  + ]:    2234940 :                 if (ml) return ml;
    1060         [ +  + ]:     613275 :                 if (ty == (jl_value_t*)jl_any_type)
    1061                 :      37799 :                     break;
    1062                 :     575476 :                 ty = (jl_value_t*)((jl_datatype_t*)ty)->super;
    1063                 :            :             }
    1064                 :            :         }
    1065                 :            :     }
    1066                 :     985927 :     jl_typemap_entry_t *linear = jl_atomic_load_relaxed(&cache->linear);
    1067         [ +  + ]:     985927 :     if (linear != (jl_typemap_entry_t*)jl_nothing) {
    1068                 :     229454 :         jl_typemap_entry_t *ml = jl_typemap_entry_assoc_exact(linear, arg1, args, n, world);
    1069         [ +  + ]:     229454 :         if (ml) return ml;
    1070                 :            :     }
    1071                 :     765452 :     jl_typemap_t *cacheany = jl_atomic_load_relaxed(&cache->any);
    1072         [ +  + ]:     765452 :     if (cacheany != (jl_typemap_t*)jl_nothing)
    1073                 :     588435 :         return jl_typemap_assoc_exact(cacheany, arg1, args, n, offs+1, world);
    1074                 :     177017 :     return NULL;
    1075                 :            : }
    1076                 :            : 
    1077                 :            : 
    1078                 :            : // ----- Method List Insertion Management ----- //
    1079                 :            : 
    1080                 :     190254 : static unsigned jl_typemap_list_count_locked(jl_typemap_entry_t *ml) JL_NOTSAFEPOINT
    1081                 :            : {
    1082                 :     190254 :     unsigned count = 0;
    1083         [ +  + ]:     826284 :     while (ml != (void*)jl_nothing) {
    1084                 :     636030 :         count++;
    1085                 :     636030 :         ml = jl_atomic_load_relaxed(&ml->next);
    1086                 :            :     }
    1087                 :     190254 :     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                 :       4544 : static jl_typemap_level_t *jl_new_typemap_level(void)
    1093                 :            : {
    1094                 :       4544 :     jl_task_t *ct = jl_current_task;
    1095                 :            :     jl_typemap_level_t *cache =
    1096                 :       4544 :         (jl_typemap_level_t*)jl_gc_alloc(ct->ptls, sizeof(jl_typemap_level_t),
    1097                 :            :                                          jl_typemap_level_type);
    1098                 :       4544 :     jl_atomic_store_relaxed(&cache->arg1, (jl_array_t*)jl_an_empty_vec_any);
    1099                 :       4544 :     jl_atomic_store_relaxed(&cache->targ, (jl_array_t*)jl_an_empty_vec_any);
    1100                 :       4544 :     jl_atomic_store_relaxed(&cache->name1, (jl_array_t*)jl_an_empty_vec_any);
    1101                 :       4544 :     jl_atomic_store_relaxed(&cache->tname, (jl_array_t*)jl_an_empty_vec_any);
    1102                 :       4544 :     jl_atomic_store_relaxed(&cache->linear, (jl_typemap_entry_t*)jl_nothing);
    1103                 :       4544 :     jl_atomic_store_relaxed(&cache->any, jl_nothing);
    1104                 :       4544 :     return cache;
    1105                 :            : }
    1106                 :            : 
    1107                 :       4544 : 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                 :       4544 :     jl_typemap_level_t *cache = jl_new_typemap_level();
    1111                 :       4544 :     jl_typemap_entry_t *next = NULL;
    1112                 :       4544 :     JL_GC_PUSH3(&cache, &next, &ml);
    1113         [ +  + ]:      63616 :     while (ml != (void*)jl_nothing) {
    1114                 :      59072 :         next = jl_atomic_load_relaxed(&ml->next);
    1115                 :      59072 :         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                 :      59072 :         jl_typemap_level_insert_(map, cache, ml, offs);
    1119                 :      59072 :         ml = next;
    1120                 :            :     }
    1121                 :       4544 :     JL_GC_POP();
    1122                 :       4544 :     return cache;
    1123                 :            : }
    1124                 :            : 
    1125                 :     193189 : 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                 :     193189 :     jl_typemap_entry_t *l = jl_atomic_load_relaxed(pml);
    1130         [ +  + ]:     215184 :     while ((jl_value_t*)l != jl_nothing) {
    1131   [ +  +  +  + ]:     164444 :         if (newrec->isleafsig || !l->isleafsig)
    1132   [ +  +  +  + ]:     155143 :             if (newrec->issimplesig || !l->issimplesig)
    1133                 :            :                 break;
    1134                 :      21995 :         pml = &l->next;
    1135                 :      21995 :         parent = (jl_value_t*)l;
    1136                 :      21995 :         l = jl_atomic_load_relaxed(&l->next);
    1137                 :            :     }
    1138                 :     193189 :     jl_atomic_store_relaxed(&newrec->next, l);
    1139                 :     193189 :     jl_gc_wb(newrec, l);
    1140                 :     193189 :     jl_atomic_store_release(pml, newrec);
    1141                 :     193189 :     jl_gc_wb(parent, newrec);
    1142                 :     193189 : }
    1143                 :            : 
    1144                 :     663606 : 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                 :     663606 :     jl_typemap_t *ml = jl_atomic_load_relaxed(pml);
    1149         [ +  + ]:     663606 :     if (jl_typeof(ml) == (jl_value_t*)jl_typemap_level_type) {
    1150                 :     473352 :         jl_typemap_level_insert_(map, (jl_typemap_level_t*)ml, newrec, offs);
    1151                 :     473352 :         return;
    1152                 :            :     }
    1153                 :            : 
    1154                 :     190254 :     unsigned count = jl_typemap_list_count_locked((jl_typemap_entry_t*)ml);
    1155         [ +  + ]:     190254 :     if (count > MAX_METHLIST_COUNT) {
    1156                 :       4544 :         ml = (jl_typemap_t*)jl_method_convert_list_to_cache(
    1157                 :            :             map, (jl_typemap_entry_t*)ml, offs);
    1158                 :       4544 :         jl_atomic_store_release(pml, ml);
    1159                 :       4544 :         jl_gc_wb(parent, ml);
    1160                 :       4544 :         jl_typemap_level_insert_(map, (jl_typemap_level_t*)ml, newrec, offs);
    1161                 :       4544 :         return;
    1162                 :            :     }
    1163                 :            : 
    1164                 :     185710 :     jl_typemap_list_insert_(map, (_Atomic(jl_typemap_entry_t*)*)pml,
    1165                 :            :         parent, newrec);
    1166                 :            : }
    1167                 :            : 
    1168                 :     521207 : 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                 :     521207 :     jl_array_t *cache = jl_atomic_load_relaxed(pcache);
    1173                 :     521207 :     _Atomic(jl_typemap_t*) *pml = mtcache_hash_lookup_bp(cache, key);
    1174         [ +  + ]:     521207 :     if (pml != NULL)
    1175                 :     338084 :         jl_typemap_insert_generic(map, pml, (jl_value_t*)cache, newrec, offs+1);
    1176                 :            :     else
    1177                 :     183123 :         mtcache_hash_insert(pcache, parent, key, (jl_typemap_t*)newrec);
    1178                 :     521207 : }
    1179                 :            : 
    1180                 :     536968 : 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                 :     536968 :     jl_value_t *ttypes = jl_unwrap_unionall((jl_value_t*)newrec->sig);
    1184                 :     536968 :     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                 :     536968 :     int isva = 0;
    1188         [ +  + ]:     536968 :     if (l <= offs + 1) {
    1189                 :     108232 :         t1 = jl_tparam(ttypes, l - 1);
    1190         [ +  + ]:     108232 :         if (jl_is_vararg(t1)) {
    1191                 :       5714 :             isva = 1;
    1192                 :       5714 :             t1 = jl_unwrap_vararg(t1);
    1193                 :            :         }
    1194         [ +  + ]:     102518 :         else if (l <= offs) {
    1195                 :       5214 :             t1 = NULL;
    1196                 :            :         }
    1197                 :            :     }
    1198         [ +  + ]:     428736 :     else if (l > offs) {
    1199                 :     428715 :         t1 = jl_tparam(ttypes, offs);
    1200                 :            :     }
    1201                 :            :     else {
    1202                 :         21 :         t1 = NULL;
    1203                 :            :     }
    1204         [ +  + ]:     536968 :     if (t1 == (jl_value_t*)jl_typeofbottom_type)
    1205                 :        219 :         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   [ +  +  +  + ]:     536968 :     if (t1 && jl_is_any(t1)) {
    1208                 :       8282 :         jl_typemap_insert_generic(map, &cache->any, (jl_value_t*)cache, newrec, offs+1);
    1209                 :       8282 :         return;
    1210                 :            :     }
    1211                 :            :     // Don't put Varargs in the optimized caches (too hard to handle in lookup and bp)
    1212   [ +  +  +  + ]:     528686 :     if (t1 && !isva) {
    1213                 :            :         // try to put in leaf type caches
    1214         [ +  + ]:     523232 :         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                 :     162158 :             jl_value_t *a0 = jl_tparam0(t1);
    1218         [ +  + ]:     162158 :             if (is_cache_leaf(a0, 1)) {
    1219                 :      53683 :                 jl_typemap_array_insert_(map, &cache->targ, a0, newrec, (jl_value_t*)cache, offs);
    1220                 :      53683 :                 return;
    1221                 :            :             }
    1222                 :            :         }
    1223         [ +  + ]:     469549 :         if (is_cache_leaf(t1, 0)) {
    1224                 :     280867 :             jl_typemap_array_insert_(map, &cache->arg1, t1, newrec, (jl_value_t*)cache, offs);
    1225                 :     280867 :             return;
    1226                 :            :         }
    1227                 :            : 
    1228                 :            :         // try to put in TypeName caches
    1229                 :            :         jl_value_t *a0;
    1230                 :     188682 :         t1 = jl_unwrap_unionall(t1);
    1231         [ +  + ]:     188682 :         if (jl_is_type_type(t1)) {
    1232                 :     112386 :             a0 = jl_type_extract_name(jl_tparam0(t1));
    1233         [ +  + ]:     112386 :             jl_datatype_t *super = a0 ? (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper) : jl_any_type;
    1234                 :     112386 :             jl_typemap_array_insert_(map, &cache->tname, (jl_value_t*)super->name, newrec, (jl_value_t*)cache, offs);
    1235                 :     112386 :             return;
    1236                 :            :         }
    1237                 :      76296 :         a0 = jl_type_extract_name(t1);
    1238   [ +  +  +  - ]:      76296 :         if (a0 && a0 != (jl_value_t*)jl_any_type->name) {
    1239                 :      74271 :             jl_typemap_array_insert_(map, &cache->name1, a0, newrec, (jl_value_t*)cache, offs);
    1240                 :      74271 :             return;
    1241                 :            :         }
    1242                 :            :     }
    1243                 :       7479 :     jl_typemap_list_insert_(map, &cache->linear, (jl_value_t*)cache, newrec);
    1244                 :            : }
    1245                 :            : 
    1246                 :    1680760 : 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                 :    1680760 :     jl_task_t *ct = jl_current_task;
    1251   [ +  -  +  - ]:    1680760 :     assert(min_world > 0 && max_world > 0);
    1252         [ +  + ]:    1680760 :     if (!simpletype)
    1253                 :    1238270 :         simpletype = (jl_tupletype_t*)jl_nothing;
    1254                 :    1680760 :     jl_value_t *ttype = jl_unwrap_unionall((jl_value_t*)type);
    1255         [ -  + ]:    1680760 :     assert(jl_is_tuple_type(ttype));
    1256                 :            :     // compute the complexity of this type signature
    1257                 :    1680760 :     int isva = jl_is_va_tuple((jl_datatype_t*)ttype);
    1258                 :    1680760 :     int issimplesig = !jl_is_unionall(type); // a TypeVar environment needs a complex matching test
    1259   [ +  +  +  + ]:    1680760 :     int isleafsig = issimplesig && !isva; // entirely leaf types don't need to be sorted
    1260                 :            :     size_t i, l;
    1261   [ +  +  +  + ]:    6739290 :     for (i = 0, l = jl_nparams(ttype); i < l && issimplesig; i++) {
    1262                 :    5058520 :         jl_value_t *decl = jl_tparam(ttype, i);
    1263         [ +  + ]:    5058520 :         if (jl_is_kind(decl))
    1264                 :       2382 :             isleafsig = 0; // Type{} may have a higher priority than a kind
    1265         [ +  + ]:    5056140 :         else if (jl_is_type_type(decl))
    1266                 :     402236 :             isleafsig = 0; // Type{} may need special processing to compute the match
    1267         [ +  + ]:    4653910 :         else if (jl_is_vararg(decl))
    1268                 :      20950 :             isleafsig = 0; // makes iteration easier when the endpoints are the same
    1269         [ +  + ]:    4632960 :         else if (decl == (jl_value_t*)jl_any_type)
    1270                 :      31866 :             isleafsig = 0; // Any needs to go in the general cache
    1271         [ +  + ]:    4601090 :         else if (!jl_is_concrete_type(decl)) // anything else needs to go through the general subtyping test
    1272                 :     133044 :             isleafsig = issimplesig = 0;
    1273                 :            :     }
    1274                 :            : 
    1275                 :            :     jl_typemap_entry_t *newrec =
    1276                 :    1680760 :         (jl_typemap_entry_t*)jl_gc_alloc(ct->ptls, sizeof(jl_typemap_entry_t),
    1277                 :            :                                          jl_typemap_entry_type);
    1278                 :    1680760 :     newrec->sig = type;
    1279                 :    1680760 :     newrec->simplesig = simpletype;
    1280                 :    1680760 :     newrec->func.value = newvalue;
    1281                 :    1680760 :     newrec->guardsigs = guardsigs;
    1282                 :    1680760 :     jl_atomic_store_relaxed(&newrec->next, (jl_typemap_entry_t*)jl_nothing);
    1283                 :    1680760 :     newrec->min_world = min_world;
    1284                 :    1680760 :     newrec->max_world = max_world;
    1285                 :    1680760 :     newrec->va = isva;
    1286                 :    1680760 :     newrec->issimplesig = issimplesig;
    1287                 :    1680760 :     newrec->isleafsig = isleafsig;
    1288                 :    1680760 :     return newrec;
    1289                 :            : }
    1290                 :            : 
    1291                 :     317240 : void jl_typemap_insert(_Atomic(jl_typemap_t *) *pcache, jl_value_t *parent,
    1292                 :            :         jl_typemap_entry_t *newrec, int8_t offs)
    1293                 :            : {
    1294                 :     317240 :     jl_typemap_t *cache = jl_atomic_load_relaxed(pcache);
    1295                 :     317240 :     jl_typemap_insert_generic(cache, pcache, parent, newrec, offs);
    1296                 :     317240 : }
    1297                 :            : 
    1298                 :            : #ifdef __cplusplus
    1299                 :            : }
    1300                 :            : #endif

Generated by: LCOV version 1.14