@@ -1888,6 +1888,11 @@ jl_lambda_info_t *jl_get_specialization1(jl_tupletype_t *types)
1888
1888
return NULL ;
1889
1889
}
1890
1890
1891
+ JL_DLLEXPORT void jl_compile_hint (jl_tupletype_t * types )
1892
+ {
1893
+ (void )jl_get_specialization1 (types );
1894
+ }
1895
+
1891
1896
// add type of `f` to front of argument tuple type
1892
1897
jl_tupletype_t * jl_argtype_with_function (jl_function_t * f , jl_tupletype_t * types )
1893
1898
{
@@ -2158,13 +2163,6 @@ static int _compile_all_enq(jl_typemap_entry_t *ml, void *env)
2158
2163
return 1 ;
2159
2164
}
2160
2165
2161
- static void _compile_all_enq_mt (jl_methtable_t * mt , jl_array_t * found )
2162
- {
2163
- if (mt == NULL || (jl_value_t * )mt == jl_nothing ) return ;
2164
- jl_typemap_visitor (mt -> defs , _compile_all_enq , (void * )found );
2165
- jl_typemap_visitor (mt -> cache , _compile_all_enq , (void * )found );
2166
- }
2167
-
2168
2166
static void _compile_all_enq_module (jl_module_t * m , jl_array_t * found )
2169
2167
{
2170
2168
// scan through all types reachable from 'v' and
@@ -2178,7 +2176,11 @@ static void _compile_all_enq_module(jl_module_t *m, jl_array_t *found)
2178
2176
if (jl_is_datatype (v )) {
2179
2177
jl_typename_t * tn = ((jl_datatype_t * )v )-> name ;
2180
2178
if (tn -> module == m && tn -> name == b -> name ) {
2181
- _compile_all_enq_mt (tn -> mt , found );
2179
+ jl_methtable_t * mt = tn -> mt ;
2180
+ if (mt != NULL && (jl_value_t * )mt != jl_nothing ) {
2181
+ jl_typemap_visitor (mt -> defs , _compile_all_enq , (void * )found );
2182
+ jl_typemap_visitor (mt -> cache , _compile_all_enq , (void * )found );
2183
+ }
2182
2184
}
2183
2185
}
2184
2186
else if (jl_is_module (v )) {
@@ -2193,11 +2195,10 @@ static void _compile_all_enq_module(jl_module_t *m, jl_array_t *found)
2193
2195
}
2194
2196
}
2195
2197
2196
- void jl_compile_all (void )
2198
+ static void jl_compile_all (void )
2197
2199
{
2198
2200
// this "found" array will contain
2199
- // LambdaInfos that need to be compiled
2200
- // and (generic-function, method) pairs that may be optimized (and need to be compiled)
2201
+ // TypeMapEntries for Methods and LambdaInfos that need to be compiled
2201
2202
jl_array_t * m = jl_alloc_cell_1d (0 );
2202
2203
JL_GC_PUSH1 (& m );
2203
2204
while (1 ) {
@@ -2210,12 +2211,81 @@ void jl_compile_all(void)
2210
2211
}
2211
2212
JL_GC_POP ();
2212
2213
}
2213
- //
2214
- JL_DLLEXPORT void jl_compile_hint ( jl_tupletype_t * types )
2214
+
2215
+ static int _precompile_enq_tfunc ( jl_typemap_entry_t * l , void * closure )
2215
2216
{
2216
- (void )jl_get_specialization1 (types );
2217
+ if (jl_is_lambda_info (l -> func .value ) && !l -> func .linfo -> functionID )
2218
+ jl_cell_1d_push (closure , (jl_value_t * )l -> func .linfo -> specTypes );
2219
+ return 1 ;
2220
+ }
2221
+
2222
+ static int _precompile_enq_spec (jl_typemap_entry_t * def , void * closure )
2223
+ {
2224
+ jl_array_t * spec = def -> func .method -> specializations ;
2225
+ if (spec == NULL )
2226
+ return 1 ;
2227
+ size_t i , l ;
2228
+ for (i = 0 , l = jl_array_len (spec ); i < l ; i ++ ) {
2229
+ jl_value_t * li = jl_cellref (spec , i );
2230
+ if (jl_is_lambda_info (li ) && !((jl_lambda_info_t * )li )-> functionID )
2231
+ jl_cell_1d_push (closure , (jl_value_t * )((jl_lambda_info_t * )li )-> specTypes );
2232
+ }
2233
+ jl_typemap_visitor (def -> func .method -> tfunc , _precompile_enq_tfunc , closure );
2234
+ return 1 ;
2235
+ }
2236
+
2237
+ static void _precompile_enq_module (jl_module_t * m , jl_array_t * unspec )
2238
+ {
2239
+ // removes all method caches
2240
+ size_t i ;
2241
+ void * * table = m -> bindings .table ;
2242
+ for (i = 1 ; i < m -> bindings .size ; i += 2 ) {
2243
+ if (table [i ] != HT_NOTFOUND ) {
2244
+ jl_binding_t * b = (jl_binding_t * )table [i ];
2245
+ if (b -> owner == m && b -> value && b -> constp ) {
2246
+ if (jl_is_datatype (b -> value )) {
2247
+ jl_typename_t * tn = ((jl_datatype_t * )b -> value )-> name ;
2248
+ if (tn -> module == m && tn -> name == b -> name ) {
2249
+ jl_methtable_t * mt = tn -> mt ;
2250
+ if (mt != NULL && (jl_value_t * )mt != jl_nothing ) {
2251
+ jl_typemap_visitor (mt -> defs , _precompile_enq_spec , (void * )unspec );
2252
+ }
2253
+ }
2254
+ }
2255
+ else if (jl_is_module (b -> value )) {
2256
+ jl_module_t * child = (jl_module_t * )b -> value ;
2257
+ if (child != m && child -> parent == m && child -> name == b -> name ) {
2258
+ // this is the original/primary binding for the submodule
2259
+ _precompile_enq_module ((jl_module_t * )b -> value , unspec );
2260
+ }
2261
+ }
2262
+ }
2263
+ }
2264
+ }
2217
2265
}
2218
2266
2267
+ static void jl_compile_specializations (void )
2268
+ {
2269
+ // this "found" array will contain function
2270
+ // type signatures that were inferred but haven't been compiled
2271
+ jl_array_t * m = jl_alloc_cell_1d (0 );
2272
+ JL_GC_PUSH1 (& m );
2273
+ _precompile_enq_module (jl_main_module , m );
2274
+ size_t i , l ;
2275
+ for (i = 0 , l = jl_array_len (m ); i < l ; i ++ ) {
2276
+ jl_compile_hint ((jl_tupletype_t * )jl_cellref (m , i ));
2277
+ }
2278
+ JL_GC_POP ();
2279
+ }
2280
+
2281
+ void jl_precompile (int all ) {
2282
+ jl_compile_specializations ();
2283
+ if (all )
2284
+ jl_compile_all ();
2285
+ }
2286
+
2287
+ //
2288
+
2219
2289
#ifdef JL_TRACE
2220
2290
static int trace_en = 0 ;
2221
2291
static int error_en = 1 ;
0 commit comments