Skip to content

Commit 7fef1c5

Browse files
committed
Make compiler module purging opt-in
We run it before module verification but, as module verification now loads many modules, that was negatively impacting compilation times.
1 parent 7048f60 commit 7fef1c5

3 files changed

Lines changed: 24 additions & 9 deletions

File tree

lib/elixir/lib/kernel/parallel_compiler.ex

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ defmodule Kernel.ParallelCompiler do
3535
dest: Path.t(),
3636
beam_timestamp: term(),
3737
return_diagnostics: boolean(),
38-
max_concurrency: pos_integer()
38+
max_concurrency: pos_integer(),
39+
purge_compiler_modules: boolean()
3940
]
4041

4142
@typedoc """
@@ -200,6 +201,9 @@ defmodule Kernel.ParallelCompiler do
200201
* `:profile` - if set to `:time` measure the compilation time of each compilation cycle
201202
and group pass checker
202203
204+
* `:purge_compiler_modules` - if set to `true`, automatically purge compilation modules
205+
after compilation (see `Code.purge_compiler_modules/0`)
206+
203207
* `:dest` - the destination directory for the BEAM files. When using `compile/2`,
204208
this information is only used to properly annotate the BEAM files before
205209
they are loaded into memory. If you want a file to actually be written to
@@ -338,6 +342,13 @@ defmodule Kernel.ParallelCompiler do
338342
threshold = Keyword.get(options, :long_compilation_threshold, 10) * 1000
339343
timer_ref = Process.send_after(self(), :threshold_check, threshold)
340344

345+
purge_compiler_modules =
346+
if Keyword.get(options, :purge_compiler_modules, false) do
347+
fn -> :elixir_code_server.cast(:purge_compiler_modules) end
348+
else
349+
fn -> :ok end
350+
end
351+
341352
{outcome, state} =
342353
spawn_workers(files, %{}, %{}, [], %{}, [], [], %{
343354
beam_timestamp: Keyword.get(options, :beam_timestamp),
@@ -353,7 +364,8 @@ defmodule Kernel.ParallelCompiler do
353364
long_compilation_threshold: threshold,
354365
schedulers: schedulers,
355366
checker: checker,
356-
verification?: Keyword.get(options, :verification, true)
367+
verification?: Keyword.get(options, :verification, true),
368+
purge_compiler_modules: purge_compiler_modules
357369
})
358370

359371
Process.cancel_timer(state.timer_ref)
@@ -570,11 +582,11 @@ defmodule Kernel.ParallelCompiler do
570582

571583
case cycle_return do
572584
{:runtime, dependent_modules, extra_warnings} ->
573-
:elixir_code_server.cast(:purge_compiler_modules)
585+
state.purge_compiler_modules.()
574586
verify_modules(result, extra_warnings ++ warnings, dependent_modules, state)
575587

576588
{:compile, [], extra_warnings} ->
577-
:elixir_code_server.cast(:purge_compiler_modules)
589+
state.purge_compiler_modules.()
578590
verify_modules(result, extra_warnings ++ warnings, [], state)
579591

580592
{:compile, more, extra_warnings} ->
@@ -879,8 +891,7 @@ defmodule Kernel.ParallelCompiler do
879891
end
880892

881893
defp return_error(warnings, errors, state, fun) do
882-
# Also prune compiler modules in case of errors
883-
:elixir_code_server.cast(:purge_compiler_modules)
894+
state.purge_compiler_modules.()
884895

885896
errors =
886897
Enum.map(errors, fn {%{file: file} = diagnostic, read_snippet} ->

lib/mix/lib/mix/compilers/elixir.ex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,9 +1039,9 @@ defmodule Mix.Compilers.Elixir do
10391039
parent = self()
10401040
compilation_threshold = opts[:long_compilation_threshold] || 10
10411041
verification_threshold = opts[:long_verification_threshold] || 10
1042-
profile = opts[:profile]
10431042
verbose = Keyword.get(opts, :verbose, false)
10441043
verification = Keyword.get(opts, :verification, true)
1044+
extra_opts = Keyword.take(opts, [:profile, :purge_compiler_modules])
10451045

10461046
if not verification and not Mix.debug?() do
10471047
Mix.shell().error("--no-verification flag is only recommended with MIX_DEBUG=1")
@@ -1078,11 +1078,12 @@ defmodule Mix.Compilers.Elixir do
10781078
long_verification_threshold: verification_threshold,
10791079
beam_timestamp: timestamp,
10801080
return_diagnostics: true,
1081-
profile: profile,
10821081
verification: verification
10831082
]
10841083

1085-
response = Kernel.ParallelCompiler.compile_to_path(stale, dest, compile_opts)
1084+
response =
1085+
Kernel.ParallelCompiler.compile_to_path(stale, dest, compile_opts ++ extra_opts)
1086+
10861087
send(parent, {ref, response})
10871088
end)
10881089

lib/mix/lib/mix/tasks/compile.elixir.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ defmodule Mix.Tasks.Compile.Elixir do
7878
the current working directory to be checked
7979
* `--purge-consolidation-path-if-stale PATH` - deletes and purges modules in the
8080
given protocol consolidation path if compilation is required
81+
* `--purge-compiler-modules` - automatically purge compilation modules
82+
after compilation (see `Code.purge_compiler_modules/0`)
8183
* `--profile` - if set to `time`, outputs timing information of compilation steps
8284
* `--tracer` - adds a compiler tracer in addition to any specified in the `mix.exs` file
8385
* `--verbose` - prints each file being compiled
@@ -110,6 +112,7 @@ defmodule Mix.Tasks.Compile.Elixir do
110112
long_compilation_threshold: :integer,
111113
long_verification_threshold: :integer,
112114
purge_consolidation_path_if_stale: :string,
115+
purge_compiler_modules: :boolean,
113116
profile: :string,
114117
all_warnings: :boolean,
115118
verification: :boolean,

0 commit comments

Comments
 (0)