aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2017-03-14 10:46:38 +0100
committerHans Bolinder <[email protected]>2017-06-13 13:40:26 +0200
commitce6fe3c77b31e6c0fcb13d347c3fcbbedfd544e7 (patch)
tree6b9c0adcc868f2b804129ae97f3fe85b1af693fe
parent020a8817caca2684f8241dc5f9c84a37d53b4ff7 (diff)
downloadotp-ce6fe3c77b31e6c0fcb13d347c3fcbbedfd544e7.tar.gz
otp-ce6fe3c77b31e6c0fcb13d347c3fcbbedfd544e7.tar.bz2
otp-ce6fe3c77b31e6c0fcb13d347c3fcbbedfd544e7.zip
dialyzer: Improve compression of an ETS table
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl26
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl14
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl22
3 files changed, 46 insertions, 16 deletions
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index a1a7370eff..a8422d313e 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -304,9 +304,29 @@ lookup_temp_mod_records(Mod, #codeserver{temp_records = TempRecDict}) ->
finalize_records(#codeserver{temp_records = TmpRecords,
records = Records} = CS) ->
- true = ets:delete(Records),
- ets:rename(TmpRecords, dialyzer_codeserver_records),
- CS#codeserver{temp_records = clean, records = TmpRecords}.
+ %% The annotations of the abstract code are reset as they are no
+ %% longer needed, which makes the ETS table compression better.
+ A0 = erl_anno:new(0),
+ AFun = fun(_) -> A0 end,
+ FFun = fun({F, Abs, Type}) ->
+ NewAbs = erl_parse:map_anno(AFun, Abs),
+ {F, NewAbs, Type}
+ end,
+ ArFun = fun({Arity, Fields}) -> {Arity, lists:map(FFun, Fields)} end,
+ List = dialyzer_utils:ets_tab2list(TmpRecords),
+ true = ets:delete(TmpRecords),
+ Fun = fun({Mod, Map}) ->
+ MFun =
+ fun({record, _}, {FileLine, ArityFields}) ->
+ {FileLine, lists:map(ArFun, ArityFields)};
+ (_, {{M, FileLine, Abs, Args}, Type}) ->
+ {{M, FileLine, erl_parse:map_anno(AFun, Abs), Args}, Type}
+ end,
+ {Mod, maps:map(MFun, Map)}
+ end,
+ NewList = lists:map(Fun, List),
+ true = ets:insert(Records, NewList),
+ CS#codeserver{temp_records = clean}.
-spec lookup_mod_contracts(atom(), codeserver()) -> contracts().
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index fa242555c2..1c1814e49c 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -604,20 +604,8 @@ give_away(#mini_plt{info = ETSInfo,
true = ets:give_away(ETSExpTypes, Pid, any),
ok.
-%% Somewhat slower than ets:tab2list(), but uses less memory.
tab2list(T) ->
- tab2list(ets:first(T), T, []).
-
-tab2list('$end_of_table', T, A) ->
- case ets:first(T) of % no safe_fixtable()...
- '$end_of_table' -> A;
- Key -> tab2list(Key, T, A)
- end;
-tab2list(Key, T, A) ->
- Vs = ets:lookup(T, Key),
- Key1 = ets:next(T, Key),
- ets:delete(T, Key),
- tab2list(Key1, T, Vs ++ A).
+ dialyzer_utils:ets_tab2list(T).
%%---------------------------------------------------------------------------
%% Edoc
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 7eaa03ec30..0dbb2bcf0a 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -39,6 +39,7 @@
sets_filter/2,
src_compiler_opts/0,
refold_pattern/1,
+ ets_tab2list/1,
parallelism/0,
family/1
]).
@@ -989,6 +990,27 @@ label(Tree) ->
%%------------------------------------------------------------------------------
+-spec ets_tab2list(ets:tid()) -> list().
+
+%% Deletes the contents of the table. Use:
+%% ets_tab2list(T), ets:delete(T)
+%% instead of:
+%% ets:tab2list(T), ets:delete(T)
+%% to save some memory at the expense of somewhat longer execution time.
+ets_tab2list(T) ->
+ tab2list(ets:first(T), T, []).
+
+tab2list('$end_of_table', T, A) ->
+ case ets:first(T) of % no safe_fixtable()...
+ '$end_of_table' -> A;
+ Key -> tab2list(Key, T, A)
+ end;
+tab2list(Key, T, A) ->
+ Vs = ets:lookup(T, Key),
+ Key1 = ets:next(T, Key),
+ ets:delete(T, Key),
+ tab2list(Key1, T, Vs ++ A).
+
-spec parallelism() -> integer().
parallelism() ->