Skip to content

Commit cdafd94

Browse files
committed
Build the occur walk's closure once per call
Why: `occur_reaches` passed `occur_reaches budget ty0` to `iter_type_expr` at every node, so the fast walk allocated a partial application per node it visited. `occur_reaches` now defines its walk once per call, capturing the budget and the variable, as `deep_occur_fast_absent` already does. The edges it follows and the exceptions it raises are unchanged. Measured with scripts/compilerBenchmarks.js against the previous commit: allocated words -1.58% in total, stress/TypeAliasChain.res -53%, Belt and runtime files -2% to -2.7%. On a 552 module React app (clean build, one domain) the build allocates 0.05% fewer words. A version that returns a bool instead of raising allocated more than this one (-1.27% in total), because `List.for_all` takes a closure per list. Signed-off-by: Jono Prest <jjprest@gmail.com>
1 parent 8582f18 commit cdafd94

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

‎compiler/ml/ctype.ml‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,18 +1430,23 @@ let spend budget =
14301430
(* Must follow the same edges as [occur_rec] in expression mode. Finishing
14311431
proves [occur_rec] would neither meet [ty0] nor find a [Tconstr] cycle,
14321432
its only ways to raise, and it expands types only after raising. *)
1433-
let rec occur_reaches budget ty0 ty =
1434-
match ty.desc with
1435-
| Tlink ty -> occur_reaches budget ty0 ty
1436-
| _ -> (
1437-
if ty == ty0 then raise Occur;
1438-
spend budget;
1433+
let occur_reaches ty0 ty =
1434+
let budget = ref walk_budget in
1435+
(* One closure for the whole walk, not a partial application per node. *)
1436+
let rec walk ty =
14391437
match ty.desc with
1440-
| Tobject _ | Tvariant _ -> ()
1441-
| _ -> iter_type_expr (occur_reaches budget ty0) ty)
1438+
| Tlink ty -> walk ty
1439+
| _ -> (
1440+
if ty == ty0 then raise Occur;
1441+
spend budget;
1442+
match ty.desc with
1443+
| Tobject _ | Tvariant _ -> ()
1444+
| _ -> iter_type_expr walk ty)
1445+
in
1446+
walk ty
14421447

14431448
let occur_cannot_fail ty0 ty =
1444-
match occur_reaches (ref walk_budget) ty0 ty with
1449+
match occur_reaches ty0 ty with
14451450
| () -> true
14461451
| exception (Occur | Give_up) -> false
14471452

0 commit comments

Comments
 (0)