aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2017-05-16 14:23:10 +0200
committerHans Bolinder <[email protected]>2017-06-13 13:40:26 +0200
commit3f185989845ab0324b8a96988066b644d15ab791 (patch)
tree93f76567622b252b4620029ae368d151d26d06b0 /lib/dialyzer
parent3ffed207dffdaad6924e3333f8ee30ac5920aa24 (diff)
downloadotp-3f185989845ab0324b8a96988066b644d15ab791.tar.gz
otp-3f185989845ab0324b8a96988066b644d15ab791.tar.bz2
otp-3f185989845ab0324b8a96988066b644d15ab791.zip
dialyzer: Run more of analyses in subprocess
Memory consumption is marginally reduced.
Diffstat (limited to 'lib/dialyzer')
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl82
1 files changed, 44 insertions, 38 deletions
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index e7172c2afc..a4b42c9367 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -134,26 +134,8 @@ analysis_start(Parent, Analysis, LegalWarnings) ->
Files = ordsets:from_list(Analysis#analysis.files),
{Callgraph, TmpCServer0} = compile_and_store(Files, State),
%% Remote type postprocessing
- NewCServer =
- try
- TmpCServer1 = dialyzer_utils:merge_types(TmpCServer0, Plt),
- NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer0),
- OldExpTypes0 = dialyzer_plt:get_exported_types(Plt),
- RemMods =
- [case Analysis#analysis.start_from of
- byte_code -> list_to_atom(filename:basename(F, ".beam"));
- src_code -> list_to_atom(filename:basename(F, ".erl"))
- end || F <- Files],
- OldExpTypes1 = dialyzer_utils:sets_filter(RemMods, OldExpTypes0),
- MergedExpTypes = sets:union(NewExpTypes, OldExpTypes1),
- TmpCServer2 =
- dialyzer_codeserver:finalize_exported_types(MergedExpTypes, TmpCServer1),
- erlang:garbage_collect(), % reduce heap size
- ?timing(State#analysis_state.timing_server, "remote",
- contracts_and_records(TmpCServer2, Parent))
- catch
- throw:{error, _ErrorMsg} = Error -> exit(Error)
- end,
+ Args = {Plt, Analysis, Parent},
+ NewCServer = remote_type_postprocessing(TmpCServer0, Args),
dump_callgraph(Callgraph, State, Analysis),
%% Remove all old versions of the files being analyzed
AllNodes = dialyzer_callgraph:all_nodes(Callgraph),
@@ -181,16 +163,54 @@ analysis_start(Parent, Analysis, LegalWarnings) ->
Plt4 = dialyzer_plt:delete_list(Plt3, NonExportsList),
send_analysis_done(Parent, Plt4, DocPlt).
-contracts_and_records(CodeServer, Parent) ->
- Fun = contrs_and_recs(CodeServer, Parent),
+remote_type_postprocessing(TmpCServer, Args) ->
+ Fun = fun() ->
+ exit(remote_type_postproc(TmpCServer, Args))
+ end,
{Pid, Ref} = erlang:spawn_monitor(Fun),
- dialyzer_codeserver:give_away(CodeServer, Pid),
+ dialyzer_codeserver:give_away(TmpCServer, Pid),
Pid ! {self(), go},
receive {'DOWN', Ref, process, Pid, Return} ->
skip_ets_transfer(Pid),
- Return
+ case Return of
+ {error, _ErrorMsg} = Error -> exit(Error);
+ _ -> Return
+ end
end.
+remote_type_postproc(TmpCServer0, Args) ->
+ {Plt, Analysis, Parent} = Args,
+ fun() ->
+ Caller = receive {Pid, go} -> Pid end,
+ TmpCServer1 = dialyzer_utils:merge_types(TmpCServer0, Plt),
+ NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer0),
+ OldExpTypes0 = dialyzer_plt:get_exported_types(Plt),
+ #analysis{start_from = StartFrom,
+ timing_server = TimingServer} = Analysis,
+ Files = ordsets:from_list(Analysis#analysis.files),
+ RemMods =
+ [case StartFrom of
+ byte_code -> list_to_atom(filename:basename(F, ".beam"));
+ src_code -> list_to_atom(filename:basename(F, ".erl"))
+ end || F <- Files],
+ OldExpTypes1 = dialyzer_utils:sets_filter(RemMods, OldExpTypes0),
+ MergedExpTypes = sets:union(NewExpTypes, OldExpTypes1),
+ TmpCServer2 =
+ dialyzer_codeserver:finalize_exported_types(MergedExpTypes,
+ TmpCServer1),
+ TmpServer4 =
+ ?timing
+ (TimingServer, "remote",
+ begin
+ TmpCServer3 =
+ dialyzer_utils:process_record_remote_types(TmpCServer2),
+ dialyzer_contracts:process_contract_remote_types(TmpCServer3)
+ end),
+ rcv_and_send_ext_types(Caller, Parent),
+ dialyzer_codeserver:give_away(TmpServer4, Caller),
+ TmpServer4
+ end().
+
skip_ets_transfer(Pid) ->
receive
{'ETS-TRANSFER', _Tid, Pid, _HeriData} ->
@@ -199,20 +219,6 @@ skip_ets_transfer(Pid) ->
ok
end.
--spec contrs_and_recs(dialyzer_codeserver:codeserver(), pid()) ->
- fun(() -> no_return()).
-
-contrs_and_recs(TmpCServer2, Parent) ->
- fun() ->
- Caller = receive {Pid, go} -> Pid end,
- TmpCServer3 = dialyzer_utils:process_record_remote_types(TmpCServer2),
- TmpServer4 =
- dialyzer_contracts:process_contract_remote_types(TmpCServer3),
- dialyzer_codeserver:give_away(TmpServer4, Caller),
- rcv_and_send_ext_types(Caller, Parent),
- exit(TmpServer4)
- end.
-
move_data(CServer, Plt) ->
{CServer1, Records} = dialyzer_codeserver:extract_records(CServer),
Plt1 = dialyzer_plt:insert_types(Plt, Records),