aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/src/dialyzer_codeserver.erl
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2017-01-01 19:53:36 +0100
committerHans Bolinder <[email protected]>2017-01-11 09:34:59 +0100
commit12b3790003ca2c060b6ab143dffd0c23580b5476 (patch)
tree169be0b75f0040568182fd41322b09b2b3e4a1b3 /lib/dialyzer/src/dialyzer_codeserver.erl
parent5d9e51a4271833855519df37df8f964216a0e594 (diff)
downloadotp-12b3790003ca2c060b6ab143dffd0c23580b5476.tar.gz
otp-12b3790003ca2c060b6ab143dffd0c23580b5476.tar.bz2
otp-12b3790003ca2c060b6ab143dffd0c23580b5476.zip
dialyzer: Try to reduce memory usage
The translation from forms to types is done in a separate process in an attempt to reduce peak memory usage. Expect further optimizations as it is probably not feasible in the long run to keep all type information on the heap.
Diffstat (limited to 'lib/dialyzer/src/dialyzer_codeserver.erl')
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl51
1 files changed, 35 insertions, 16 deletions
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index ba278b627a..786ed229df 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -30,6 +30,7 @@
-export([delete/1,
store_temp_contracts/4,
+ give_away/2,
finalize_contracts/1,
finalize_exported_types/2,
finalize_records/2,
@@ -85,8 +86,8 @@
-record(codeserver, {next_core_label = 0 :: label(),
code :: dict_ets(),
- exported_types :: set_ets() | 'undefined', % set(mfa())
- records :: map_ets() | 'undefined',
+ exported_types :: set_ets(), % set(mfa())
+ records :: map_ets(),
contracts :: map_ets(),
callbacks :: map_ets(),
fun_meta_info :: dict_ets(), % {mfa(), meta_info()}
@@ -132,9 +133,6 @@ ets_set_to_set(Table) ->
Fold = fun({E}, Set) -> sets:add_element(E, Set) end,
ets:foldl(Fold, sets:new(), Table).
-ets_read_concurrent_table(Name) ->
- ets:new(Name, [compressed, {read_concurrency, true}]).
-
%%--------------------------------------------------------------------
-spec new() -> codeserver().
@@ -142,9 +140,14 @@ ets_read_concurrent_table(Name) ->
new() ->
CodeOptions = [compressed, public, {read_concurrency, true}],
Code = ets:new(dialyzer_codeserver_code, CodeOptions),
+ ReadOptions = [compressed, {read_concurrency, true}],
+ [Contracts, Callbacks, Records, ExportedTypes] =
+ [ets:new(Name, ReadOptions) ||
+ Name <- [dialyzer_codeserver_contracts,
+ dialyzer_codeserver_callbacks,
+ dialyzer_codeserver_records,
+ dialyzer_codeserver_exported_types]],
TempOptions = [public, {write_concurrency, true}],
- Contracts = ets_read_concurrent_table(dialyzer_codeserver_contracts),
- Callbacks = ets_read_concurrent_table(dialyzer_codeserver_callbacks),
[Exports, FunMetaInfo, TempExportedTypes, TempRecords, TempContracts,
TempCallbacks] =
[ets:new(Name, TempOptions) ||
@@ -156,6 +159,8 @@ new() ->
#codeserver{code = Code,
exports = Exports,
fun_meta_info = FunMetaInfo,
+ exported_types = ExportedTypes,
+ records = Records,
contracts = Contracts,
callbacks = Callbacks,
temp_exported_types = TempExportedTypes,
@@ -228,12 +233,12 @@ get_exports(#codeserver{exports = Exports}) ->
-spec finalize_exported_types(sets:set(mfa()), codeserver()) -> codeserver().
-finalize_exported_types(Set, CS) ->
- ExportedTypes = ets_read_concurrent_table(dialyzer_codeserver_exported_types),
+finalize_exported_types(Set,
+ #codeserver{exported_types = ExportedTypes,
+ temp_exported_types = TempETypes} = CS) ->
true = ets_set_insert_set(Set, ExportedTypes),
- TempExpTypes = CS#codeserver.temp_exported_types,
- true = ets:delete(TempExpTypes),
- CS#codeserver{exported_types = ExportedTypes, temp_exported_types = clean}.
+ true = ets:delete(TempETypes),
+ CS#codeserver{temp_exported_types = clean}.
-spec lookup_mod_code(atom(), codeserver()) -> cerl:c_module().
@@ -297,11 +302,11 @@ set_temp_records(Dict, CS) ->
-spec finalize_records(mod_records(), codeserver()) -> codeserver().
-finalize_records(Dict, CS) ->
- true = ets:delete(CS#codeserver.temp_records),
- Records = ets_read_concurrent_table(dialyzer_codeserver_records),
+finalize_records(Dict, #codeserver{temp_records = TmpRecords,
+ records = Records} = CS) ->
+ true = ets:delete(TmpRecords),
true = ets_dict_store_dict(Dict, Records),
- CS#codeserver{records = Records, temp_records = clean}.
+ CS#codeserver{temp_records = clean}.
-spec lookup_mod_contracts(atom(), codeserver()) -> contracts().
@@ -377,6 +382,20 @@ get_temp_contracts(Mod, #codeserver{temp_contracts = TempContDict,
true = ets:delete(TempCallDict, Mod),
{Contracts, Callbacks}.
+-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.
+
-spec finalize_contracts(codeserver()) -> codeserver().
finalize_contracts(#codeserver{temp_contracts = TempContDict,