diff options
author | José Valim <[email protected]> | 2018-02-19 00:44:52 +0100 |
---|---|---|
committer | José Valim <[email protected]> | 2018-02-21 16:34:33 +0100 |
commit | 0018bf63fcce35f6704cff5c34d398b32706fd75 (patch) | |
tree | b7e0d96976e2141229a9360114ffc206015ddb2e | |
parent | 8f93219117d3c553500d7e55f1ec65cab3e1c3e0 (diff) | |
download | otp-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.erl | 20 |
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) -> |