@@ -1959,6 +1959,11 @@ jl_lambda_info_t *jl_get_specialization1(jl_tupletype_t *types)
1959
1959
return NULL ;
1960
1960
}
1961
1961
1962
+ JL_DLLEXPORT void jl_compile_hint (jl_tupletype_t * types )
1963
+ {
1964
+ (void )jl_get_specialization1 (types );
1965
+ }
1966
+
1962
1967
// add type of `f` to front of argument tuple type
1963
1968
jl_tupletype_t * jl_argtype_with_function (jl_function_t * f , jl_tupletype_t * types )
1964
1969
{
@@ -2229,13 +2234,6 @@ static int _compile_all_enq(jl_typemap_entry_t *ml, void *env)
2229
2234
return 1 ;
2230
2235
}
2231
2236
2232
- static void _compile_all_enq_mt (jl_methtable_t * mt , jl_array_t * found )
2233
- {
2234
- if (mt == NULL || (jl_value_t * )mt == jl_nothing ) return ;
2235
- jl_typemap_visitor (mt -> defs , _compile_all_enq , (void * )found );
2236
- jl_typemap_visitor (mt -> cache , _compile_all_enq , (void * )found );
2237
- }
2238
-
2239
2237
static void _compile_all_enq_module (jl_module_t * m , jl_array_t * found )
2240
2238
{
2241
2239
// scan through all types reachable from 'v' and
@@ -2249,7 +2247,11 @@ static void _compile_all_enq_module(jl_module_t *m, jl_array_t *found)
2249
2247
if (jl_is_datatype (v )) {
2250
2248
jl_typename_t * tn = ((jl_datatype_t * )v )-> name ;
2251
2249
if (tn -> module == m && tn -> name == b -> name ) {
2252
- _compile_all_enq_mt (tn -> mt , found );
2250
+ jl_methtable_t * mt = tn -> mt ;
2251
+ if (mt != NULL && (jl_value_t * )mt != jl_nothing ) {
2252
+ jl_typemap_visitor (mt -> defs , _compile_all_enq , (void * )found );
2253
+ jl_typemap_visitor (mt -> cache , _compile_all_enq , (void * )found );
2254
+ }
2253
2255
}
2254
2256
}
2255
2257
else if (jl_is_module (v )) {
@@ -2264,11 +2266,10 @@ static void _compile_all_enq_module(jl_module_t *m, jl_array_t *found)
2264
2266
}
2265
2267
}
2266
2268
2267
- void jl_compile_all (void )
2269
+ static void jl_compile_all (void )
2268
2270
{
2269
2271
// this "found" array will contain
2270
- // LambdaInfos that need to be compiled
2271
- // and (generic-function, method) pairs that may be optimized (and need to be compiled)
2272
+ // TypeMapEntries for Methods and LambdaInfos that need to be compiled
2272
2273
jl_array_t * m = jl_alloc_cell_1d (0 );
2273
2274
JL_GC_PUSH1 (& m );
2274
2275
while (1 ) {
@@ -2281,12 +2282,81 @@ void jl_compile_all(void)
2281
2282
}
2282
2283
JL_GC_POP ();
2283
2284
}
2284
- //
2285
- JL_DLLEXPORT void jl_compile_hint ( jl_tupletype_t * types )
2285
+
2286
+ static int _precompile_enq_tfunc ( jl_typemap_entry_t * l , void * closure )
2286
2287
{
2287
- (void )jl_get_specialization1 (types );
2288
+ if (jl_is_lambda_info (l -> func .value ) && !l -> func .linfo -> functionID )
2289
+ jl_cell_1d_push (closure , (jl_value_t * )l -> func .linfo -> specTypes );
2290
+ return 1 ;
2291
+ }
2292
+
2293
+ static int _precompile_enq_spec (jl_typemap_entry_t * def , void * closure )
2294
+ {
2295
+ jl_array_t * spec = def -> func .method -> specializations ;
2296
+ if (spec == NULL )
2297
+ return 1 ;
2298
+ size_t i , l ;
2299
+ for (i = 0 , l = jl_array_len (spec ); i < l ; i ++ ) {
2300
+ jl_value_t * li = jl_cellref (spec , i );
2301
+ if (jl_is_lambda_info (li ) && !((jl_lambda_info_t * )li )-> functionID )
2302
+ jl_cell_1d_push (closure , (jl_value_t * )((jl_lambda_info_t * )li )-> specTypes );
2303
+ }
2304
+ jl_typemap_visitor (def -> func .method -> tfunc , _precompile_enq_tfunc , closure );
2305
+ return 1 ;
2306
+ }
2307
+
2308
+ static void _precompile_enq_module (jl_module_t * m , jl_array_t * unspec )
2309
+ {
2310
+ // removes all method caches
2311
+ size_t i ;
2312
+ void * * table = m -> bindings .table ;
2313
+ for (i = 1 ; i < m -> bindings .size ; i += 2 ) {
2314
+ if (table [i ] != HT_NOTFOUND ) {
2315
+ jl_binding_t * b = (jl_binding_t * )table [i ];
2316
+ if (b -> owner == m && b -> value && b -> constp ) {
2317
+ if (jl_is_datatype (b -> value )) {
2318
+ jl_typename_t * tn = ((jl_datatype_t * )b -> value )-> name ;
2319
+ if (tn -> module == m && tn -> name == b -> name ) {
2320
+ jl_methtable_t * mt = tn -> mt ;
2321
+ if (mt != NULL && (jl_value_t * )mt != jl_nothing ) {
2322
+ jl_typemap_visitor (mt -> defs , _precompile_enq_spec , (void * )unspec );
2323
+ }
2324
+ }
2325
+ }
2326
+ else if (jl_is_module (b -> value )) {
2327
+ jl_module_t * child = (jl_module_t * )b -> value ;
2328
+ if (child != m && child -> parent == m && child -> name == b -> name ) {
2329
+ // this is the original/primary binding for the submodule
2330
+ _precompile_enq_module ((jl_module_t * )b -> value , unspec );
2331
+ }
2332
+ }
2333
+ }
2334
+ }
2335
+ }
2336
+ }
2337
+
2338
+ static void jl_compile_specializations (void )
2339
+ {
2340
+ // this "found" array will contain function
2341
+ // type signatures that were inferred but haven't been compiled
2342
+ jl_array_t * m = jl_alloc_cell_1d (0 );
2343
+ JL_GC_PUSH1 (& m );
2344
+ _precompile_enq_module (jl_main_module , m );
2345
+ size_t i , l ;
2346
+ for (i = 0 , l = jl_array_len (m ); i < l ; i ++ ) {
2347
+ jl_compile_hint ((jl_tupletype_t * )jl_cellref (m , i ));
2348
+ }
2349
+ JL_GC_POP ();
2288
2350
}
2289
2351
2352
+ void jl_precompile (int all ) {
2353
+ jl_compile_specializations ();
2354
+ if (all )
2355
+ jl_compile_all ();
2356
+ }
2357
+
2358
+ //
2359
+
2290
2360
#ifdef JL_TRACE
2291
2361
static int trace_en = 0 ;
2292
2362
static int error_en = 1 ;
0 commit comments