aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/src
diff options
context:
space:
mode:
authorStavros Aronis <[email protected]>2012-02-09 14:57:06 +0100
committerHenrik Nord <[email protected]>2012-05-21 15:31:16 +0200
commitf912241953ecece658f429ffd09f77e2e49ffa4c (patch)
treecede8f68da8715e7ce374166be60eb79d10e8adc /lib/dialyzer/src
parent8a3ea1fa45cac31cdc1241a6ea1e1a0d857c1429 (diff)
downloadotp-f912241953ecece658f429ffd09f77e2e49ffa4c.tar.gz
otp-f912241953ecece658f429ffd09f77e2e49ffa4c.tar.bz2
otp-f912241953ecece658f429ffd09f77e2e49ffa4c.zip
Success typing analysis uses ETS tables for necessary plt info
Only the info and contracts dicts were neccessary for success typing inference and these have been converted to ETS tables.
Diffstat (limited to 'lib/dialyzer/src')
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl65
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl4
2 files changed, 58 insertions, 11 deletions
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index 01d777d138..0c0773e977 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -55,7 +55,10 @@
plt_and_info_from_file/1,
get_specs/1,
get_specs/4,
- to_file/4]).
+ to_file/4,
+ get_mini_plt/1,
+ restore_full_plt/2
+ ]).
%% Debug utilities
-export([pp_non_returning/0, pp_mod/1]).
@@ -82,7 +85,12 @@
contracts = table_new() :: dict(),
callbacks = table_new() :: dict(),
exported_types = sets:new() :: set()}).
--opaque plt() :: #plt{}.
+
+-record(mini_plt, {info :: ets:tid(),
+ contracts :: ets:tid()
+ }).
+
+-opaque plt() :: #plt{} | #mini_plt{}.
-include("dialyzer.hrl").
@@ -133,7 +141,10 @@ delete_list(#plt{info = Info, types = Types,
-spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt().
insert_contract_list(#plt{contracts = Contracts} = PLT, List) ->
- PLT#plt{contracts = table_insert_list(Contracts, List)}.
+ PLT#plt{contracts = table_insert_list(Contracts, List)};
+insert_contract_list(#mini_plt{contracts = Contracts} = PLT, List) ->
+ true = ets:insert(Contracts, List),
+ PLT.
-spec insert_callbacks(plt(), dialyzer_codeserver:codeserver()) -> plt().
@@ -145,7 +156,10 @@ insert_callbacks(#plt{callbacks = Callbacks} = Plt, Codeserver) ->
lookup_contract(#plt{contracts = Contracts},
{M, F, _} = MFA) when is_atom(M), is_atom(F) ->
- table_lookup(Contracts, MFA).
+ table_lookup(Contracts, MFA);
+lookup_contract(#mini_plt{contracts = ETSContracts},
+ {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
+ ets_table_lookup(ETSContracts, MFA).
-spec lookup_callbacks(plt(), module()) ->
[{mfa(), {{Filename::string(), Line::pos_integer()}, #contract{}}}].
@@ -158,15 +172,23 @@ lookup_callbacks(#plt{callbacks = Callbacks}, Mod) when is_atom(Mod) ->
-spec insert_list(plt(), [{mfa() | integer(), ret_args_types()}]) -> plt().
insert_list(#plt{info = Info} = PLT, List) ->
- PLT#plt{info = table_insert_list(Info, List)}.
+ PLT#plt{info = table_insert_list(Info, List)};
+insert_list(#mini_plt{info = Info} = PLT, List) ->
+ true = ets:insert(Info, List),
+ PLT.
-spec lookup(plt(), integer() | mfa_patt()) ->
'none' | {'value', ret_args_types()}.
-lookup(#plt{info = Info}, {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
- table_lookup(Info, MFA);
-lookup(#plt{info = Info}, Label) when is_integer(Label) ->
- table_lookup(Info, Label).
+lookup(Plt, {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
+ lookup_1(Plt, MFA);
+lookup(Plt, Label) when is_integer(Label) ->
+ lookup_1(Plt, Label).
+
+lookup_1(#plt{info = Info}, MFAorLabel) ->
+ table_lookup(Info, MFAorLabel);
+lookup_1(#mini_plt{info = Info}, MFAorLabel) ->
+ ets_table_lookup(Info, MFAorLabel).
-spec insert_types(plt(), dict()) -> plt().
@@ -493,6 +515,24 @@ init_md5_list_1([], DiffList, Acc) ->
init_md5_list_1(Md5List, [], Acc) ->
{ok, lists:reverse(Acc, Md5List)}.
+-spec get_mini_plt(plt()) -> plt().
+
+get_mini_plt(#plt{info = Info, contracts = Contracts}) ->
+ ETSInfo = ets:new(plt_info, [public]),
+ ETSContracts = ets:new(plt_contracts, [public]),
+ true = ets:insert(ETSInfo, dict:to_list(Info)),
+ true = ets:insert(ETSContracts, dict:to_list(Contracts)),
+ #mini_plt{info = ETSInfo, contracts = ETSContracts}.
+
+-spec restore_full_plt(plt(), plt()) -> plt().
+
+restore_full_plt(#mini_plt{info = ETSInfo, contracts = ETSContracts}, Plt) ->
+ Info = dict:from_list(ets:tab2list(ETSInfo)),
+ Contracts = dict:from_list(ets:tab2list(ETSContracts)),
+ ets:delete(ETSContracts),
+ ets:delete(ETSInfo),
+ Plt#plt{info = Info, contracts = Contracts}.
+
%%---------------------------------------------------------------------------
%% Edoc
@@ -585,6 +625,13 @@ table_lookup(Plt, Obj) ->
{ok, Val} -> {value, Val}
end.
+ets_table_lookup(Plt, Obj) ->
+ try ets:lookup_element(Plt, Obj, 2) of
+ Val -> {value, Val}
+ catch
+ _:_ -> none
+ end.
+
table_lookup_module(Plt, Mod) ->
List = dict:fold(fun(Key, Val, Acc) ->
case Key of
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index 2c2c39951c..9e6702b484 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -75,10 +75,10 @@ analyze_callgraph(Callgraph, Plt, Codeserver) ->
dialyzer_plt:plt().
analyze_callgraph(Callgraph, Plt, Codeserver, Parent) ->
- State = #st{callgraph = Callgraph, plt = Plt,
+ State = #st{callgraph = Callgraph, plt = dialyzer_plt:get_mini_plt(Plt),
codeserver = Codeserver, parent = Parent},
NewState = get_refined_success_typings(State),
- NewState#st.plt.
+ dialyzer_plt:restore_full_plt(NewState#st.plt, Plt).
%%--------------------------------------------------------------------