@@ -1406,21 +1406,31 @@ static int invalidate_mt_cache(jl_typemap_entry_t *oldentry, void *closure0)
1406
1406
if (oldentry -> max_world == ~(size_t )0 ) {
1407
1407
jl_method_instance_t * mi = oldentry -> func .linfo ;
1408
1408
jl_method_t * m = mi -> def .method ;
1409
+ int intersects = 0 ;
1409
1410
if (jl_is_method (env -> shadowed )) {
1410
- if ((jl_value_t * )m == env -> shadowed )
1411
- oldentry -> max_world = env -> max_world ;
1411
+ if ((jl_value_t * )m == env -> shadowed ) {
1412
+ intersects = 1 ;
1413
+ }
1412
1414
}
1413
1415
else {
1414
1416
assert (jl_is_array (env -> shadowed ));
1415
1417
jl_typemap_entry_t * * d = (jl_typemap_entry_t * * )jl_array_ptr_data (env -> shadowed );
1416
1418
size_t i , n = jl_array_len (env -> shadowed );
1417
1419
for (i = 0 ; i < n ; i ++ ) {
1418
1420
if (m == d [i ]-> func .method ) {
1419
- oldentry -> max_world = env -> max_world ;
1420
- return 1 ;
1421
+ intersects = 1 ;
1422
+ break ;
1421
1423
}
1422
1424
}
1423
1425
}
1426
+ if (intersects ) {
1427
+ if (JL_DEBUG_METHOD_INVALIDATION ) {
1428
+ jl_uv_puts (JL_STDOUT , "-- " , 4 );
1429
+ jl_static_show (JL_STDOUT , (jl_value_t * )mi );
1430
+ jl_uv_puts (JL_STDOUT , "\n" , 1 );
1431
+ }
1432
+ oldentry -> max_world = env -> max_world ;
1433
+ }
1424
1434
}
1425
1435
return 1 ;
1426
1436
}
@@ -2118,14 +2128,25 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t **args, uint32
2118
2128
jl_methtable_t * mt = NULL ;
2119
2129
int i ;
2120
2130
// check each cache entry to see if it matches
2121
- for (i = 0 ; i < 4 ; i ++ ) {
2122
- entry = call_cache [cache_idx [i ]];
2123
- if (entry && nargs == jl_svec_len (entry -> sig -> parameters ) &&
2124
- sig_match_fast (args , jl_svec_data (entry -> sig -> parameters ), 0 , nargs ) &&
2125
- world >= entry -> min_world && world <= entry -> max_world ) {
2126
- break ;
2127
- }
2128
- }
2131
+ //#pragma unroll
2132
+ //for (i = 0; i < 4; i++) {
2133
+ // LOOP_BODY(i);
2134
+ //}
2135
+ #define LOOP_BODY (_i ) do { \
2136
+ i = _i; \
2137
+ entry = call_cache[cache_idx[i]]; \
2138
+ if (entry && nargs == jl_svec_len(entry->sig->parameters) && \
2139
+ sig_match_fast(args, jl_svec_data(entry->sig->parameters), 0, nargs) && \
2140
+ world >= entry->min_world && world <= entry->max_world) { \
2141
+ goto have_entry; \
2142
+ } \
2143
+ } while (0);
2144
+ LOOP_BODY (0 );
2145
+ LOOP_BODY (1 );
2146
+ LOOP_BODY (2 );
2147
+ LOOP_BODY (3 );
2148
+ #undef LOOP_BODY
2149
+ i = 4 ;
2129
2150
// if no method was found in the associative cache, check the full cache
2130
2151
if (i == 4 ) {
2131
2152
JL_TIMING (METHOD_LOOKUP_FAST );
@@ -2136,11 +2157,13 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t **args, uint32
2136
2157
// put the entry into the cache if it's valid for a leafsig lookup,
2137
2158
// using pick_which to slightly randomize where it ends up
2138
2159
call_cache [cache_idx [++ pick_which [cache_idx [0 ]] & 3 ]] = entry ;
2160
+ goto have_entry ;
2139
2161
}
2140
2162
}
2141
2163
2142
- jl_method_instance_t * mfunc = NULL ;
2164
+ jl_method_instance_t * mfunc ;
2143
2165
if (entry ) {
2166
+ have_entry :
2144
2167
mfunc = entry -> func .linfo ;
2145
2168
}
2146
2169
else {
@@ -2177,11 +2200,23 @@ jl_method_instance_t *jl_lookup_generic(jl_value_t **args, uint32_t nargs, uint3
2177
2200
2178
2201
JL_DLLEXPORT jl_value_t * jl_apply_generic (jl_value_t * * args , uint32_t nargs )
2179
2202
{
2203
+ size_t world = jl_get_ptls_states ()-> world_age ;
2180
2204
jl_method_instance_t * mfunc = jl_lookup_generic_ (args , nargs ,
2181
2205
jl_int32hash_fast (jl_return_address ()),
2182
- jl_get_ptls_states () -> world_age );
2206
+ world );
2183
2207
JL_GC_PROMISE_ROOTED (mfunc );
2184
- jl_value_t * res = jl_invoke (mfunc , args , nargs );
2208
+ jl_value_t * res ;
2209
+ // manually inline key parts of jl_invoke:
2210
+ jl_code_instance_t * codeinst = mfunc -> cache ;
2211
+ while (codeinst ) {
2212
+ if (codeinst -> min_world <= world && world <= codeinst -> max_world && codeinst -> invoke != NULL ) {
2213
+ res = codeinst -> invoke (codeinst , args , nargs );
2214
+ return verify_type (res );
2215
+ }
2216
+ codeinst = codeinst -> next ;
2217
+ }
2218
+ codeinst = jl_compile_method_internal (mfunc , world );
2219
+ res = codeinst -> invoke (codeinst , args , nargs );
2185
2220
return verify_type (res );
2186
2221
}
2187
2222
0 commit comments