diff options
author | Stavros Aronis <[email protected]> | 2012-02-09 14:57:06 +0100 |
---|---|---|
committer | Henrik Nord <[email protected]> | 2012-05-21 15:31:16 +0200 |
commit | f912241953ecece658f429ffd09f77e2e49ffa4c (patch) | |
tree | cede8f68da8715e7ce374166be60eb79d10e8adc /lib/dialyzer/src | |
parent | 8a3ea1fa45cac31cdc1241a6ea1e1a0d857c1429 (diff) | |
download | otp-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.erl | 65 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_succ_typings.erl | 4 |
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). %%-------------------------------------------------------------------- |