@@ -2255,6 +2255,39 @@ JL_DLLEXPORT jl_value_t *jl_normalize_to_compilable_sig(jl_methtable_t *mt, jl_t
2255
2255
return is_compileable ? (jl_value_t * )tt : jl_nothing ;
2256
2256
}
2257
2257
2258
+ // return a MethodInstance for a compileable method_match
2259
+ jl_method_instance_t * jl_method_match_to_mi (jl_method_match_t * match , size_t world , size_t min_valid , size_t max_valid , int mt_cache )
2260
+ {
2261
+ jl_method_t * m = match -> method ;
2262
+ jl_svec_t * env = match -> sparams ;
2263
+ jl_tupletype_t * ti = match -> spec_types ;
2264
+ jl_method_instance_t * mi = NULL ;
2265
+ if (jl_is_datatype (ti )) {
2266
+ jl_methtable_t * mt = jl_method_get_table (m );
2267
+ if ((jl_value_t * )mt != jl_nothing ) {
2268
+ // get the specialization without caching it
2269
+ if (mt_cache && ((jl_datatype_t * )ti )-> isdispatchtuple ) {
2270
+ // Since we also use this presence in the cache
2271
+ // to trigger compilation when producing `.ji` files,
2272
+ // inject it there now if we think it will be
2273
+ // used via dispatch later (e.g. because it was hinted via a call to `precompile`)
2274
+ JL_LOCK (& mt -> writelock );
2275
+ mi = cache_method (mt , & mt -> cache , (jl_value_t * )mt , ti , m , world , min_valid , max_valid , env );
2276
+ JL_UNLOCK (& mt -> writelock );
2277
+ }
2278
+ else {
2279
+ jl_value_t * tt = jl_normalize_to_compilable_sig (mt , ti , env , m );
2280
+ JL_GC_PUSH1 (& tt );
2281
+ if (tt != jl_nothing ) {
2282
+ mi = jl_specializations_get_linfo (m , (jl_value_t * )tt , env );
2283
+ }
2284
+ JL_GC_POP ();
2285
+ }
2286
+ }
2287
+ }
2288
+ return mi ;
2289
+ }
2290
+
2258
2291
// compile-time method lookup
2259
2292
jl_method_instance_t * jl_get_specialization1 (jl_tupletype_t * types JL_PROPAGATES_ROOT , size_t world , size_t * min_valid , size_t * max_valid , int mt_cache )
2260
2293
{
@@ -2274,36 +2307,52 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES
2274
2307
* max_valid = max_valid2 ;
2275
2308
if (matches == jl_false || jl_array_len (matches ) != 1 || ambig )
2276
2309
return NULL ;
2277
- jl_value_t * tt = NULL ;
2278
- JL_GC_PUSH2 (& matches , & tt );
2310
+ JL_GC_PUSH1 (& matches );
2279
2311
jl_method_match_t * match = (jl_method_match_t * )jl_array_ptr_ref (matches , 0 );
2280
- jl_method_t * m = match -> method ;
2281
- jl_svec_t * env = match -> sparams ;
2282
- jl_tupletype_t * ti = match -> spec_types ;
2283
- jl_method_instance_t * nf = NULL ;
2284
- if (jl_is_datatype (ti )) {
2285
- jl_methtable_t * mt = jl_method_get_table (m );
2286
- if ((jl_value_t * )mt != jl_nothing ) {
2287
- // get the specialization without caching it
2288
- if (mt_cache && ((jl_datatype_t * )ti )-> isdispatchtuple ) {
2289
- // Since we also use this presence in the cache
2290
- // to trigger compilation when producing `.ji` files,
2291
- // inject it there now if we think it will be
2292
- // used via dispatch later (e.g. because it was hinted via a call to `precompile`)
2293
- JL_LOCK (& mt -> writelock );
2294
- nf = cache_method (mt , & mt -> cache , (jl_value_t * )mt , ti , m , world , min_valid2 , max_valid2 , env );
2295
- JL_UNLOCK (& mt -> writelock );
2296
- }
2297
- else {
2298
- tt = jl_normalize_to_compilable_sig (mt , ti , env , m );
2299
- if (tt != jl_nothing ) {
2300
- nf = jl_specializations_get_linfo (m , (jl_value_t * )tt , env );
2301
- }
2312
+ jl_method_instance_t * mi = jl_method_match_to_mi (match , world , min_valid2 , max_valid2 , mt_cache );
2313
+ JL_GC_POP ();
2314
+ return mi ;
2315
+ }
2316
+
2317
+ // Get a MethodInstance for a precompile() call. This uses a special kind of lookup that
2318
+ // tries to find a method for which the requested signature is compileable.
2319
+ jl_method_instance_t * jl_get_compile_hint_specialization (jl_tupletype_t * types JL_PROPAGATES_ROOT , size_t world , size_t * min_valid , size_t * max_valid , int mt_cache )
2320
+ {
2321
+ if (jl_has_free_typevars ((jl_value_t * )types ))
2322
+ return NULL ; // don't poison the cache due to a malformed query
2323
+ if (!jl_has_concrete_subtype ((jl_value_t * )types ))
2324
+ return NULL ;
2325
+
2326
+ size_t min_valid2 = 1 ;
2327
+ size_t max_valid2 = ~(size_t )0 ;
2328
+ int ambig = 0 ;
2329
+ jl_value_t * matches = jl_matching_methods (types , jl_nothing , -1 , 1 , world , & min_valid2 , & max_valid2 , & ambig );
2330
+ if (* min_valid < min_valid2 )
2331
+ * min_valid = min_valid2 ;
2332
+ if (* max_valid > max_valid2 )
2333
+ * max_valid = max_valid2 ;
2334
+ size_t i , n = jl_array_len (matches );
2335
+ if (n == 0 )
2336
+ return NULL ;
2337
+ JL_GC_PUSH1 (& matches );
2338
+ jl_method_match_t * match = NULL ;
2339
+ if (n == 1 ) {
2340
+ match = (jl_method_match_t * )jl_array_ptr_ref (matches , 0 );
2341
+ }
2342
+ else {
2343
+ for (i = 0 ; i < n ; i ++ ) {
2344
+ jl_method_match_t * match1 = (jl_method_match_t * )jl_array_ptr_ref (matches , i );
2345
+ if (jl_isa_compileable_sig (match1 -> spec_types , match1 -> method )) {
2346
+ match = match1 ;
2347
+ break ;
2302
2348
}
2303
2349
}
2304
2350
}
2351
+ jl_method_instance_t * mi = NULL ;
2352
+ if (match != NULL )
2353
+ mi = jl_method_match_to_mi (match , world , min_valid2 , max_valid2 , mt_cache );
2305
2354
JL_GC_POP ();
2306
- return nf ;
2355
+ return mi ;
2307
2356
}
2308
2357
2309
2358
static void _generate_from_hint (jl_method_instance_t * mi , size_t world )
@@ -2370,7 +2419,7 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types)
2370
2419
size_t world = jl_atomic_load_acquire (& jl_world_counter );
2371
2420
size_t min_valid = 0 ;
2372
2421
size_t max_valid = ~(size_t )0 ;
2373
- jl_method_instance_t * mi = jl_get_specialization1 (types , world , & min_valid , & max_valid , 1 );
2422
+ jl_method_instance_t * mi = jl_get_compile_hint_specialization (types , world , & min_valid , & max_valid , 1 );
2374
2423
if (mi == NULL )
2375
2424
return 0 ;
2376
2425
JL_GC_PROMISE_ROOTED (mi );
0 commit comments