aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl29
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl16
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl68
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl21
4 files changed, 73 insertions, 61 deletions
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index a3bb2b858d..aeeb895a0c 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -153,16 +153,12 @@ analysis_start(Parent, Analysis, LegalWarnings) ->
catch
throw:{error, _ErrorMsg} = Error -> exit(Error)
end,
- NewPlt0 = dialyzer_plt:insert_types(Plt, dialyzer_codeserver:get_records(NewCServer)),
- ExpTypes = dialyzer_codeserver:get_exported_types(NewCServer),
- NewPlt1 = dialyzer_plt:insert_exported_types(NewPlt0, ExpTypes),
- State0 = State#analysis_state{plt = NewPlt1},
- dump_callgraph(Callgraph, State0, Analysis),
+ dump_callgraph(Callgraph, State, Analysis),
%% Remove all old versions of the files being analyzed
AllNodes = dialyzer_callgraph:all_nodes(Callgraph),
- Plt1_a = dialyzer_plt:delete_list(NewPlt1, AllNodes),
+ Plt1_a = dialyzer_plt:delete_list(Plt, AllNodes),
Plt1 = dialyzer_plt:insert_callbacks(Plt1_a, NewCServer),
- State1 = State0#analysis_state{codeserver = NewCServer, plt = Plt1},
+ State1 = State#analysis_state{codeserver = NewCServer, plt = Plt1},
Exports = dialyzer_codeserver:get_exports(NewCServer),
NonExports = sets:subtract(sets:from_list(AllNodes), Exports),
NonExportsList = sets:to_list(NonExports),
@@ -172,14 +168,17 @@ analysis_start(Parent, Analysis, LegalWarnings) ->
false -> Callgraph
end,
State2 = analyze_callgraph(NewCallgraph, State1),
- #analysis_state{plt = MiniPlt2, doc_plt = DocPlt} = State2,
+ #analysis_state{plt = MiniPlt2,
+ doc_plt = DocPlt,
+ codeserver = Codeserver0} = State2,
+ {Codeserver, MiniPlt3} = move_data(Codeserver0, MiniPlt2),
dialyzer_callgraph:dispose_race_server(NewCallgraph),
rcv_and_send_ext_types(Parent),
%% Since the PLT is never used, a dummy is sent:
DummyPlt = dialyzer_plt:new(),
- send_codeserver_plt(Parent, CServer, DummyPlt),
- MiniPlt3 = dialyzer_plt:delete_list(MiniPlt2, NonExportsList),
- send_analysis_done(Parent, MiniPlt3, DocPlt).
+ send_codeserver_plt(Parent, Codeserver, DummyPlt),
+ MiniPlt4 = dialyzer_plt:delete_list(MiniPlt3, NonExportsList),
+ send_analysis_done(Parent, MiniPlt4, DocPlt).
contracts_and_records(CodeServer) ->
Fun = contrs_and_recs(CodeServer),
@@ -203,6 +202,13 @@ contrs_and_recs(TmpCServer2) ->
exit(TmpServer4)
end.
+move_data(CServer, MiniPlt) ->
+ {CServer1, Records} = dialyzer_codeserver:extract_records(CServer),
+ MiniPlt1 = dialyzer_plt:insert_types(MiniPlt, Records),
+ {NewCServer, ExpTypes} = dialyzer_codeserver:extract_exported_types(CServer1),
+ NewMiniPlt = dialyzer_plt:insert_exported_types(MiniPlt1, ExpTypes),
+ {NewCServer, NewMiniPlt}.
+
analyze_callgraph(Callgraph, #analysis_state{codeserver = Codeserver,
doc_plt = DocPlt,
plt = Plt,
@@ -597,6 +603,7 @@ send_ext_types(Parent, ExtTypes) ->
ok.
send_codeserver_plt(Parent, CServer, Plt) ->
+ ok = dialyzer_codeserver:give_away(CServer, Parent),
Parent ! {self(), cserver, CServer, Plt},
ok.
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index 158ee761af..93200f53d2 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -30,6 +30,8 @@
-record(cl_state,
{backend_pid :: pid() | 'undefined',
+ code_server = none :: 'none'
+ | dialyzer_codeserver:codeserver(),
erlang_mode = false :: boolean(),
external_calls = [] :: [mfa()],
external_types = [] :: [mfa()],
@@ -630,6 +632,9 @@ cl_loop(State, LogCache) ->
{BackendPid, warnings, Warnings} ->
NewState = store_warnings(State, Warnings),
cl_loop(NewState, LogCache);
+ {BackendPid, cserver, CodeServer, _Plt} -> % Plt is ignored
+ NewState = State#cl_state{code_server = CodeServer},
+ cl_loop(NewState, LogCache);
{BackendPid, done, NewMiniPlt, _NewDocPlt} ->
return_value(State, NewMiniPlt);
{BackendPid, ext_calls, ExtCalls} ->
@@ -647,7 +652,6 @@ cl_loop(State, LogCache) ->
cl_error(State, Msg);
_Other ->
%% io:format("Received ~p\n", [_Other]),
- %% Note: {BackendPid, cserver, CodeServer, Plt} is ignored.
cl_loop(State, LogCache)
end.
@@ -688,12 +692,20 @@ cl_error(State, Msg) ->
maybe_close_output_file(State),
throw({dialyzer_error, lists:flatten(Msg)}).
-return_value(State = #cl_state{erlang_mode = ErlangMode,
+return_value(State = #cl_state{code_server = CodeServer,
+ erlang_mode = ErlangMode,
mod_deps = ModDeps,
output_plt = OutputPlt,
plt_info = PltInfo,
stored_warnings = StoredWarnings},
MiniPlt) ->
+ %% Just for now:
+ case CodeServer =:= none of
+ true ->
+ ok;
+ false ->
+ dialyzer_codeserver:delete(CodeServer)
+ end,
case OutputPlt =:= none of
true ->
dialyzer_plt:delete(MiniPlt);
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index e15569388e..a1a7370eff 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -30,9 +30,10 @@
get_contracts/1,
get_callbacks/1,
get_exported_types/1,
+ extract_exported_types/1,
get_exports/1,
- get_records/1,
get_records_table/1,
+ extract_records/1,
get_next_core_label/1,
get_temp_contracts/2,
all_temp_modules/1,
@@ -54,7 +55,6 @@
lookup_meta_info/2,
new/0,
set_next_core_label/2,
- set_temp_records/2,
store_temp_records/3,
translate_fake_file/3]).
@@ -69,7 +69,6 @@
-type set_ets() :: ets:tid().
-type types() :: erl_types:type_table().
--type mod_records() :: erl_types:mod_records().
-type contracts() :: #{mfa() => dialyzer_contracts:file_contract()}.
@@ -81,8 +80,8 @@
-record(codeserver, {next_core_label = 0 :: label(),
code :: dict_ets(),
- exported_types :: set_ets(), % set(mfa())
- records :: map_ets(),
+ exported_types :: 'clean' | set_ets(), % set(mfa())
+ records :: 'clean' | map_ets(),
contracts :: map_ets(),
callbacks :: map_ets(),
fun_meta_info :: dict_ets(), % {mfa(), meta_info()}
@@ -108,9 +107,6 @@ ets_map_store(Key, Element, Table) ->
true = ets:insert(Table, {Key, Element}),
Table.
-ets_dict_store_dict(Dict, Table) ->
- true = ets:insert(Table, dict:to_list(Dict)).
-
ets_dict_to_dict(Table) ->
Fold = fun({Key,Value}, Dict) -> dict:store(Key, Value, Dict) end,
ets:foldl(Fold, dict:new(), Table).
@@ -165,11 +161,8 @@ new() ->
-spec delete(codeserver()) -> 'ok'.
-delete(#codeserver{code = Code, exported_types = ExportedTypes,
- records = Records, contracts = Contracts,
- callbacks = Callbacks}) ->
- lists:foreach(fun ets:delete/1,
- [Code, ExportedTypes, Records, Contracts, Callbacks]).
+delete(CServer) ->
+ lists:foreach(fun(Table) -> true = ets:delete(Table) end, tables(CServer)).
-spec insert(atom(), cerl:c_module(), codeserver()) -> codeserver().
@@ -223,6 +216,11 @@ is_exported(MFA, #codeserver{exports = Exports}) ->
get_exported_types(#codeserver{exported_types = ExpTypes}) ->
ets_set_to_set(ExpTypes).
+-spec extract_exported_types(codeserver()) -> {codeserver(), set_ets()}.
+
+extract_exported_types(#codeserver{exported_types = ExpTypes} = CS) ->
+ {CS#codeserver{exported_types = 'clean'}, ExpTypes}.
+
-spec get_exports(codeserver()) -> sets:set(mfa()).
get_exports(#codeserver{exports = Exports}) ->
@@ -275,10 +273,10 @@ lookup_mod_records(Mod, #codeserver{records = RecDict}) when is_atom(Mod) ->
get_records_table(#codeserver{records = RecDict}) ->
RecDict.
--spec get_records(codeserver()) -> mod_records().
+-spec extract_records(codeserver()) -> {codeserver(), map_ets()}.
-get_records(#codeserver{records = RecDict}) ->
- ets_dict_to_dict(RecDict).
+extract_records(#codeserver{records = RecDict} = CS) ->
+ {CS#codeserver{records = clean}, RecDict}.
-spec store_temp_records(module(), types(), codeserver()) -> codeserver().
@@ -302,14 +300,6 @@ lookup_temp_mod_records(Mod, #codeserver{temp_records = TempRecDict}) ->
{ok, Map} -> Map
end.
--spec set_temp_records(mod_records(), codeserver()) -> codeserver().
-
-set_temp_records(Dict, CS) ->
- true = ets:delete(CS#codeserver.temp_records),
- TempRecords = ets:new(dialyzer_codeserver_temp_records,[]),
- true = ets_dict_store_dict(Dict, TempRecords),
- CS#codeserver{temp_records = TempRecords}.
-
-spec finalize_records(codeserver()) -> codeserver().
finalize_records(#codeserver{temp_records = TmpRecords,
@@ -399,17 +389,25 @@ get_temp_contracts(Mod, #codeserver{temp_contracts = TempContDict,
-spec give_away(codeserver(), pid()) -> 'ok'.
-give_away(#codeserver{temp_records = TempRecords,
- temp_contracts = TempContracts,
- temp_callbacks = TempCallbacks,
- records = Records,
- contracts = Contracts,
- callbacks = Callbacks}, Pid) ->
- _ = [true = ets:give_away(Table, Pid, any) ||
- Table <- [TempRecords, TempContracts, TempCallbacks,
- Records, Contracts, Callbacks],
- Table =/= clean],
- ok.
+give_away(CServer, Pid) ->
+ lists:foreach(fun(Table) -> true = ets:give_away(Table, Pid, any)
+ end, tables(CServer)).
+
+tables(#codeserver{code = Code,
+ fun_meta_info = FunMetaInfo,
+ exports = Exports,
+ temp_exported_types = TempExpTypes,
+ temp_records = TempRecords,
+ temp_contracts = TempContracts,
+ temp_callbacks = TempCallbacks,
+ exported_types = ExportedTypes,
+ records = Records,
+ contracts = Contracts,
+ callbacks = Callbacks}) ->
+ [Table || Table <- [Code, FunMetaInfo, Exports, TempExpTypes,
+ TempRecords, TempContracts, TempCallbacks,
+ ExportedTypes, Records, Contracts, Callbacks],
+ Table =/= clean].
-spec finalize_contracts(codeserver()) -> codeserver().
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index 511a17d577..26dfeac71e 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -31,10 +31,8 @@
included_files/1,
from_file/1,
get_default_plt/0,
- get_types/1,
get_module_types/2,
get_exported_types/1,
- %% insert/3,
insert_list/2,
insert_contract_list/2,
insert_callbacks/2,
@@ -189,20 +187,17 @@ lookup(Plt, Label) when is_integer(Label) ->
lookup_1(#mini_plt{info = Info}, MFAorLabel) ->
ets_table_lookup(Info, MFAorLabel).
--spec insert_types(plt(), erl_types:mod_records()) -> plt().
+-spec insert_types(plt(), ets:tid()) -> plt().
-insert_types(PLT, Rec) ->
- PLT#plt{types = Rec}.
+insert_types(MiniPLT, Records) ->
+ ets:rename(Records, plt_types),
+ MiniPLT#mini_plt{types = Records}.
--spec insert_exported_types(plt(), sets:set()) -> plt().
+-spec insert_exported_types(plt(), ets:tid()) -> plt().
-insert_exported_types(PLT, Set) ->
- PLT#plt{exported_types = Set}.
-
--spec get_types(plt()) -> erl_types:mod_records().
-
-get_types(#plt{types = Types}) ->
- Types.
+insert_exported_types(MiniPLT, ExpTypes) ->
+ ets:rename(ExpTypes, plt_exported_types),
+ MiniPLT#mini_plt{exported_types = ExpTypes}.
-spec get_module_types(plt(), atom()) ->
'none' | {'value', erl_types:type_table()}.