Skip to content

Compact heap before calling C linker #33

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
May 18, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions backend/asmlink.ml
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,16 @@ let call_linker file_list startup_file output_name =
if not (exitcode = 0)
then raise(Error(Linking_error exitcode))

let reset () =
Cmi_consistbl.clear crc_interfaces;
Cmx_consistbl.clear crc_implementations;
String.Tbl.reset implementations_defined;
cmx_required := [];
String.Tbl.reset interfaces;
implementations := [];
lib_ccobjs := [];
lib_ccopts := []

(* Main entry point *)

let link ~ppf_dump objfiles output_name =
Expand Down Expand Up @@ -395,6 +405,20 @@ let link ~ppf_dump objfiles output_name =
~asm_filename:startup ~keep_asm:!Clflags.keep_startup_file
~obj_filename:startup_obj
(fun () -> make_startup_file ~ppf_dump units_tolink);
(* Clear all state and compact before calling the linker, because the linker
can use a lot of memory, and this reduces the peak memory usage by freeing
most of the memory from this process before the linker starts using memory.

On a link where this frees up around 1.1GB of memory this takes around 0.6s. We
only take this time on large links where the number of parallel linking jobs is
likely to be constrained by total system memory. *)
let _minor, _promoted, major_words = Gc.counters () in
(* Uses [major_words] because it doesn't require a heap traversal to compute and
for this workload a majority of major words are live at this point. *)
if major_words > 500_000_000.0 /. 8.0 then
Profile.record_call "asmlink_compact" (fun () ->
reset ();
Gc.compact ());
Misc.try_finally
(fun () ->
call_linker (List.map object_file_name objfiles)
Expand Down Expand Up @@ -467,13 +491,3 @@ let () =
| Error err -> Some (Location.error_of_printer_file report_error err)
| _ -> None
)

let reset () =
Cmi_consistbl.clear crc_interfaces;
Cmx_consistbl.clear crc_implementations;
String.Tbl.reset implementations_defined;
cmx_required := [];
String.Tbl.reset interfaces;
implementations := [];
lib_ccobjs := [];
lib_ccopts := []