Skip to content

Commit 99cc59c

Browse files
authored
typeintersect: allocation tuning for large UnionAll (#54745)
This PR tries to reduce the allocation caused by `save_env` by skipping `alloc_env` and truncating env size when possible.
2 parents 675da9d + 5d69bbb commit 99cc59c

File tree

1 file changed

+39
-5
lines changed

1 file changed

+39
-5
lines changed

src/subtype.c

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,24 +2423,47 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e,
24232423
if (obviously_egal(x, y))
24242424
return x;
24252425

2426+
jl_varbinding_t *vars = NULL;
2427+
jl_varbinding_t *bbprev = NULL;
2428+
jl_varbinding_t *xb = jl_is_typevar(x) ? lookup(e, (jl_tvar_t *)x) : NULL;
2429+
jl_varbinding_t *yb = jl_is_typevar(y) ? lookup(e, (jl_tvar_t *)y) : NULL;
2430+
int simple_x = !jl_has_free_typevars(!jl_is_typevar(x) ? x : xb ? xb->ub : ((jl_tvar_t *)x)->ub);
2431+
int simple_y = !jl_has_free_typevars(!jl_is_typevar(y) ? y : yb ? yb->ub : ((jl_tvar_t *)y)->ub);
2432+
if (simple_x && simple_y && !(xb && yb)) {
2433+
vars = e->vars;
2434+
e->vars = xb ? xb : yb;
2435+
if (e->vars != NULL) {
2436+
bbprev = e->vars->prev;
2437+
e->vars->prev = NULL;
2438+
}
2439+
}
24262440
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions);
24272441
int savedepth = e->invdepth;
24282442
e->invdepth = depth;
24292443
jl_value_t *res = intersect_all(x, y, e);
24302444
e->invdepth = savedepth;
24312445
pop_unionstate(&e->Runions, &oldRunions);
2446+
if (bbprev) e->vars->prev = bbprev;
2447+
if (vars) e->vars = vars;
24322448
return res;
24332449
}
24342450

24352451
static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t *e, int8_t R, int param)
24362452
{
2437-
if (param == 2 || (!jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u))) {
2453+
int no_free = !jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u);
2454+
if (param == 2 || no_free) {
24382455
jl_value_t *a=NULL, *b=NULL;
24392456
JL_GC_PUSH2(&a, &b);
2457+
jl_varbinding_t *vars = NULL;
2458+
if (no_free) {
2459+
vars = e->vars;
2460+
e->vars = NULL;
2461+
}
24402462
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions);
24412463
a = R ? intersect_all(x, u->a, e) : intersect_all(u->a, x, e);
24422464
b = R ? intersect_all(x, u->b, e) : intersect_all(u->b, x, e);
24432465
pop_unionstate(&e->Runions, &oldRunions);
2466+
if (vars) e->vars = vars;
24442467
jl_value_t *i = simple_join(a,b);
24452468
JL_GC_POP();
24462469
return i;
@@ -4138,19 +4161,30 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
41384161
save_env(e, &se, 1);
41394162
int niter = 0, total_iter = 0;
41404163
is[0] = intersect(x, y, e, 0); // root
4141-
if (is[0] != jl_bottom_type)
4164+
if (is[0] == jl_bottom_type) {
4165+
restore_env(e, &se, 1);
4166+
}
4167+
else if (!e->emptiness_only && has_next_union_state(e, 1)) {
41424168
niter = merge_env(e, &me, &se, niter);
4143-
restore_env(e, &se, 1);
4169+
restore_env(e, &se, 1);
4170+
}
41444171
while (next_union_state(e, 1)) {
41454172
if (e->emptiness_only && is[0] != jl_bottom_type)
41464173
break;
41474174
e->Runions.depth = 0;
41484175
e->Runions.more = 0;
41494176

41504177
is[1] = intersect(x, y, e, 0);
4151-
if (is[1] != jl_bottom_type)
4178+
if (is[1] == jl_bottom_type) {
4179+
restore_env(e, &se, 1);
4180+
}
4181+
else if (niter > 0 || (!e->emptiness_only && has_next_union_state(e, 1))) {
41524182
niter = merge_env(e, &me, &se, niter);
4153-
restore_env(e, &se, 1);
4183+
restore_env(e, &se, 1);
4184+
}
4185+
else {
4186+
assert(is[0] == jl_bottom_type);
4187+
}
41544188
if (is[0] == jl_bottom_type)
41554189
is[0] = is[1];
41564190
else if (is[1] != jl_bottom_type) {

0 commit comments

Comments
 (0)