Skip to content

Commit 125ca2c

Browse files
committed
fixup! internals: better representation for code
1 parent b284b98 commit 125ca2c

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

src/gf.c

+50-15
Original file line numberDiff line numberDiff line change
@@ -1406,21 +1406,31 @@ static int invalidate_mt_cache(jl_typemap_entry_t *oldentry, void *closure0)
14061406
if (oldentry->max_world == ~(size_t)0) {
14071407
jl_method_instance_t *mi = oldentry->func.linfo;
14081408
jl_method_t *m = mi->def.method;
1409+
int intersects = 0;
14091410
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+
}
14121414
}
14131415
else {
14141416
assert(jl_is_array(env->shadowed));
14151417
jl_typemap_entry_t **d = (jl_typemap_entry_t**)jl_array_ptr_data(env->shadowed);
14161418
size_t i, n = jl_array_len(env->shadowed);
14171419
for (i = 0; i < n; i++) {
14181420
if (m == d[i]->func.method) {
1419-
oldentry->max_world = env->max_world;
1420-
return 1;
1421+
intersects = 1;
1422+
break;
14211423
}
14221424
}
14231425
}
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+
}
14241434
}
14251435
return 1;
14261436
}
@@ -2118,14 +2128,25 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t **args, uint32
21182128
jl_methtable_t *mt = NULL;
21192129
int i;
21202130
// 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;
21292150
// if no method was found in the associative cache, check the full cache
21302151
if (i == 4) {
21312152
JL_TIMING(METHOD_LOOKUP_FAST);
@@ -2136,11 +2157,13 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t **args, uint32
21362157
// put the entry into the cache if it's valid for a leafsig lookup,
21372158
// using pick_which to slightly randomize where it ends up
21382159
call_cache[cache_idx[++pick_which[cache_idx[0]] & 3]] = entry;
2160+
goto have_entry;
21392161
}
21402162
}
21412163

2142-
jl_method_instance_t *mfunc = NULL;
2164+
jl_method_instance_t *mfunc;
21432165
if (entry) {
2166+
have_entry:
21442167
mfunc = entry->func.linfo;
21452168
}
21462169
else {
@@ -2177,11 +2200,23 @@ jl_method_instance_t *jl_lookup_generic(jl_value_t **args, uint32_t nargs, uint3
21772200

21782201
JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs)
21792202
{
2203+
size_t world = jl_get_ptls_states()->world_age;
21802204
jl_method_instance_t *mfunc = jl_lookup_generic_(args, nargs,
21812205
jl_int32hash_fast(jl_return_address()),
2182-
jl_get_ptls_states()->world_age);
2206+
world);
21832207
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);
21852220
return verify_type(res);
21862221
}
21872222

src/typemap.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -1016,8 +1016,14 @@ jl_typemap_entry_t *jl_typemap_insert(jl_typemap_t **cache, jl_value_t *parent,
10161016
if (ml && ml->simplesig == (void*)jl_nothing) {
10171017
if (overwritten != NULL)
10181018
*overwritten = ml->func.value;
1019-
if (newvalue == ml->func.value) // no change. TODO: involve world in computation!
1019+
if (newvalue == ml->func.value) {
1020+
// just update the existing entry to reflect new knowledge
1021+
if (ml->min_world > min_world)
1022+
ml->min_world = min_world;
1023+
if (ml->max_world < max_world)
1024+
ml->max_world = max_world;
10201025
return ml;
1026+
}
10211027
if (newvalue == NULL) // don't overwrite with guard entries
10221028
return ml;
10231029
ml->max_world = min_world - 1;

0 commit comments

Comments
 (0)