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