Skip to content

Commit 71f4b13

Browse files
authored
Allocate a value's copy closure only when the copy is deferred
Why: `components_of_module_maker` built a closure for the copy of every value it added, also when it then copied the value at once (the first time the process builds a .cmi's components, and for every module that is not part of a .cmi), and checked recorded counts against the signature by converting the count array to a list. `make_cell` now takes the substitution and the declaration and builds a closure only for a deferred copy, and the counts are checked by walking the signature with an index. Which values are deferred, the type ids they take and the components built are unchanged. Measured with scripts/compilerBenchmarks.js against the previous commit: allocated words -0.15% in total, -0.25% in the project builds (where components are built again in one process and their counts are known), -0.04% for the files compiled one by one. On a 552 module React app (clean build, one domain) the build allocates 0.2% fewer words. Signed-off-by: Jono Prest <jjprest@gmail.com>
1 parent f2872a7 commit 71f4b13

1 file changed

Lines changed: 22 additions & 19 deletions

File tree

‎compiler/ml/env.ml‎

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,20 +1821,23 @@ and components_of_module_maker
18211821
let key = Option.map (fun crc -> (crc, Path.name path)) origin in
18221822
let state = Compiler_request_state.current () in
18231823
let item_count = List.length sg in
1824+
(* Whether [counts] fit this signature: one for every value. *)
1825+
let counts_fit counts =
1826+
Array.length counts = item_count
1827+
&&
1828+
let rec fit index = function
1829+
| [] -> true
1830+
| Sig_value _ :: _ when counts.(index) < 0 -> false
1831+
| ( Sig_value _ | Sig_type _ | Sig_typext _ | Sig_module _
1832+
| Sig_modtype _ )
1833+
:: rest ->
1834+
fit (index + 1) rest
1835+
in
1836+
fit 0 sg
1837+
in
18241838
let counts =
18251839
match Option.bind key find_component_counts with
1826-
| Some counts
1827-
when Array.length counts = item_count
1828-
&& List.for_all2
1829-
(fun item count ->
1830-
match item with
1831-
| Sig_value _ -> count >= 0
1832-
| Sig_type _ | Sig_typext _ | Sig_module _ | Sig_modtype _
1833-
->
1834-
true)
1835-
sg (Array.to_list counts) ->
1836-
(* The counts fit this signature: one for every value. *)
1837-
Some counts
1840+
| Some counts when counts_fit counts -> Some counts
18381841
| Some _ | None -> None
18391842
in
18401843
(* The type ids each value takes, when the counts of these
@@ -1846,21 +1849,23 @@ and components_of_module_maker
18461849
in
18471850
let stamps_taken = ref false in
18481851
let deferred = ref 0 in
1849-
let make_cell index compute =
1852+
(* The copy is a closure only when it is deferred. *)
1853+
let make_cell index sub decl =
18501854
match (counts, recorded) with
18511855
| Some counts, _ ->
18521856
let base = state.type_node_id and count = counts.(index) in
18531857
state.type_node_id <- base + count;
18541858
incr deferred;
18551859
Comp_cell.pending (fun () ->
1856-
with_reserved_type_ids ~base ~count compute)
1860+
with_reserved_type_ids ~base ~count (fun () ->
1861+
Subst.value_description sub decl))
18571862
| None, Some recorded ->
18581863
let type0 = state.type_node_id and stamp0 = Ident.current_time () in
1859-
let result = compute () in
1864+
let result = Subst.value_description sub decl in
18601865
recorded.(index) <- state.type_node_id - type0;
18611866
if Ident.current_time () <> stamp0 then stamps_taken := true;
18621867
Comp_cell.ready result
1863-
| None, None -> Comp_cell.ready (compute ())
1868+
| None, None -> Comp_cell.ready (Subst.value_description sub decl)
18641869
in
18651870
let pl, sub = prefix_idents path sub sg in
18661871
let env = ref env in
@@ -1870,9 +1875,7 @@ and components_of_module_maker
18701875
(fun item path ->
18711876
(match item with
18721877
| Sig_value (id, decl) -> (
1873-
let decl' =
1874-
make_cell !index (fun () -> Subst.value_description sub decl)
1875-
in
1878+
let decl' = make_cell !index sub decl in
18761879
c.comp_values <- Tbl.add (Ident.name id) (decl', !pos) c.comp_values;
18771880
match decl.val_kind with
18781881
| Val_prim _ -> ()

0 commit comments

Comments
 (0)