aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <[email protected]>2018-02-19 00:44:52 +0100
committerJosé Valim <[email protected]>2018-02-21 16:34:33 +0100
commit0018bf63fcce35f6704cff5c34d398b32706fd75 (patch)
treeb7e0d96976e2141229a9360114ffc206015ddb2e
parent8f93219117d3c553500d7e55f1ec65cab3e1c3e0 (diff)
downloadotp-0018bf63fcce35f6704cff5c34d398b32706fd75.tar.gz
otp-0018bf63fcce35f6704cff5c34d398b32706fd75.tar.bz2
otp-0018bf63fcce35f6704cff5c34d398b32706fd75.zip
Compute MD5s in dialyzer using the .beam file
The previous mechanism was based on the core file which meant that for every module in the PLT, we had to fetch its .beam file, retrieve Erlang AST, compile that down to core, serialize it into a binary and then get its MD5. In a project with stdlib, kernel, elixir and a small application in the PLT, relying only on the .beam sped up --check_plt from 10s to 0.8s.
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl20
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index 95c8b5ebce..2af4534396 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -531,17 +531,19 @@ compute_md5_from_files(Files) ->
lists:keysort(1, [{F, compute_md5_from_file(F)} || F <- Files]).
compute_md5_from_file(File) ->
- case filelib:is_regular(File) of
- false ->
+ case beam_lib:all_chunks(File) of
+ {ok, _, Chunks} ->
+ %% We cannot use beam_lib:md5 because it does not consider
+ %% the debug_info chunk, where typespecs are likely stored.
+ %% So we consider almost all chunks except the useless ones.
+ Filtered = [[ID, Chunk] || {ID, Chunk} <- Chunks, ID =/= "CInf", ID =/= "Docs"],
+ erlang:md5(lists:sort(Filtered));
+ {error, beam_lib, {file_error, _, enoent}} ->
Msg = io_lib:format("Not a regular file: ~ts\n", [File]),
throw({dialyzer_error, Msg});
- true ->
- case dialyzer_utils:get_core_from_beam(File) of
- {error, Error} ->
- throw({dialyzer_error, Error});
- {ok, Core} ->
- erlang:md5(term_to_binary(Core))
- end
+ {error, beam_lib, _} ->
+ Msg = io_lib:format("Could not compute MD5 for .beam: ~ts\n", [File]),
+ throw({dialyzer_error, Msg})
end.
init_diff_list(RemoveFiles, AddFiles) ->