Skip to content

Commit 737b3cf

Browse files
committed
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 e4f5c5f commit 737b3cf

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
@@ -1745,20 +1745,23 @@ and components_of_module_maker
17451745
let key = Option.map (fun crc -> (crc, Path.name path)) origin in
17461746
let state = Compiler_request_state.current () in
17471747
let item_count = List.length sg in
1748+
(* Whether [counts] fit this signature: one for every value. *)
1749+
let counts_fit counts =
1750+
Array.length counts = item_count
1751+
&&
1752+
let rec fit index = function
1753+
| [] -> true
1754+
| Sig_value _ :: _ when counts.(index) < 0 -> false
1755+
| ( Sig_value _ | Sig_type _ | Sig_typext _ | Sig_module _
1756+
| Sig_modtype _ )
1757+
:: rest ->
1758+
fit (index + 1) rest
1759+
in
1760+
fit 0 sg
1761+
in
17481762
let counts =
17491763
match Option.bind key find_component_counts with
1750-
| Some counts
1751-
when Array.length counts = item_count
1752-
&& List.for_all2
1753-
(fun item count ->
1754-
match item with
1755-
| Sig_value _ -> count >= 0
1756-
| Sig_type _ | Sig_typext _ | Sig_module _ | Sig_modtype _
1757-
->
1758-
true)
1759-
sg (Array.to_list counts) ->
1760-
(* The counts fit this signature: one for every value. *)
1761-
Some counts
1764+
| Some counts when counts_fit counts -> Some counts
17621765
| Some _ | None -> None
17631766
in
17641767
(* The type ids each value takes, when the counts of these
@@ -1770,21 +1773,23 @@ and components_of_module_maker
17701773
in
17711774
let stamps_taken = ref false in
17721775
let deferred = ref 0 in
1773-
let make_cell index compute =
1776+
(* The copy is a closure only when it is deferred. *)
1777+
let make_cell index sub decl =
17741778
match (counts, recorded) with
17751779
| Some counts, _ ->
17761780
let base = state.type_node_id and count = counts.(index) in
17771781
state.type_node_id <- base + count;
17781782
incr deferred;
17791783
Comp_cell.pending (fun () ->
1780-
with_reserved_type_ids ~base ~count compute)
1784+
with_reserved_type_ids ~base ~count (fun () ->
1785+
Subst.value_description sub decl))
17811786
| None, Some recorded ->
17821787
let type0 = state.type_node_id and stamp0 = Ident.current_time () in
1783-
let result = compute () in
1788+
let result = Subst.value_description sub decl in
17841789
recorded.(index) <- state.type_node_id - type0;
17851790
if Ident.current_time () <> stamp0 then stamps_taken := true;
17861791
Comp_cell.ready result
1787-
| None, None -> Comp_cell.ready (compute ())
1792+
| None, None -> Comp_cell.ready (Subst.value_description sub decl)
17881793
in
17891794
let pl, sub = prefix_idents path sub sg in
17901795
let env = ref env in
@@ -1794,9 +1799,7 @@ and components_of_module_maker
17941799
(fun item path ->
17951800
(match item with
17961801
| Sig_value (id, decl) -> (
1797-
let decl' =
1798-
make_cell !index (fun () -> Subst.value_description sub decl)
1799-
in
1802+
let decl' = make_cell !index sub decl in
18001803
c.comp_values <- Tbl.add (Ident.name id) (decl', !pos) c.comp_values;
18011804
match decl.val_kind with
18021805
| Val_prim _ -> ()

0 commit comments

Comments
 (0)