aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2016-12-19 10:02:12 +0100
committerHans Bolinder <[email protected]>2017-01-11 09:34:59 +0100
commit7f3b77274958b62523e83ab2b37ad29ec9a6cf3c (patch)
tree47276a031c0210ae2f533b47962962042ec854d7
parent2bcf8a6159e3b370739b835b52b95ff73c54776f (diff)
downloadotp-7f3b77274958b62523e83ab2b37ad29ec9a6cf3c.tar.gz
otp-7f3b77274958b62523e83ab2b37ad29ec9a6cf3c.tar.bz2
otp-7f3b77274958b62523e83ab2b37ad29ec9a6cf3c.zip
dialyzer: Reduce memory consumption during 'remote' phase
The cache used for speeding up the translation from forms to types is no longer global, but reset per module. The peak memory consumption is reduced, and the added time seems to be small.
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl16
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl33
2 files changed, 25 insertions, 24 deletions
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 331786466f..82275d5df7 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -165,17 +165,15 @@ process_contract_remote_types(CodeServer) ->
{{MFA, {File, Contract, Xtra}}, C2}
end,
ModuleFun =
- fun({ModuleName, ContractDict}, C3) ->
- {NewContractList, C4} =
- lists:mapfoldl(ContractFun, C3, dict:to_list(ContractDict)),
- {{ModuleName, dict:from_list(NewContractList)}, C4}
+ fun({ModuleName, ContractDict}) ->
+ Cache = erl_types:cache__new(),
+ {NewContractList, _NewCache} =
+ lists:mapfoldl(ContractFun, Cache, dict:to_list(ContractDict)),
+ {ModuleName, dict:from_list(NewContractList)}
end,
erlang:garbage_collect(),
- Cache = erl_types:cache__new(),
- {NewContractList, C5} =
- lists:mapfoldl(ModuleFun, Cache, dict:to_list(TmpContractDict)),
- {NewCallbackList, _C6} =
- lists:mapfoldl(ModuleFun, C5, dict:to_list(TmpCallbackDict)),
+ NewContractList = lists:map(ModuleFun, dict:to_list(TmpContractDict)),
+ NewCallbackList = lists:map(ModuleFun, dict:to_list(TmpCallbackDict)),
NewContractDict = dict:from_list(NewContractList),
NewCallbackDict = dict:from_list(NewCallbackList),
%% Make sure the (huge) cache is garbage collected:
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 921644422e..5386d5f219 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -302,13 +302,11 @@ get_record_fields([], _RecDict, Acc) ->
process_record_remote_types(CServer) ->
TempRecords = dialyzer_codeserver:get_temp_records(CServer),
ExpTypes = dialyzer_codeserver:get_exported_types(CServer),
- Cache = erl_types:cache__new(),
- {TempRecords1, Cache1} =
- process_opaque_types0(TempRecords, ExpTypes, Cache),
+ TempRecords1 = process_opaque_types0(TempRecords, ExpTypes),
%% A cache (not the field type cache) is used for speeding things up a bit.
VarTable = erl_types:var_table__new(),
ModuleFun =
- fun({Module, Record}, C0) ->
+ fun({Module, Record}) ->
RecordFun =
fun({Key, Value}, C2) ->
case Key of
@@ -334,24 +332,27 @@ process_record_remote_types(CServer) ->
_Other -> {{Key, Value}, C2}
end
end,
- {RecordList, C1} =
- lists:mapfoldl(RecordFun, C0, dict:to_list(Record)),
- {{Module, dict:from_list(RecordList)}, C1}
+ Cache = erl_types:cache__new(),
+ {RecordList, _NewCache} =
+ lists:mapfoldl(RecordFun, Cache, dict:to_list(Record)),
+ {Module, dict:from_list(RecordList)}
end,
- {NewRecordsList, C1} =
- lists:mapfoldl(ModuleFun, Cache1, dict:to_list(TempRecords1)),
+ NewRecordsList = lists:map(ModuleFun, dict:to_list(TempRecords1)),
NewRecords = dict:from_list(NewRecordsList),
- _C8 = check_record_fields(NewRecords, ExpTypes, C1),
+ check_record_fields(NewRecords, ExpTypes),
dialyzer_codeserver:finalize_records(NewRecords, CServer).
%% erl_types:t_from_form() substitutes the declaration of opaque types
%% for the expanded type in some cases. To make sure the initial type,
%% any(), is not used, the expansion is done twice.
%% XXX: Recursive opaque types are not handled well.
-process_opaque_types0(TempRecords0, TempExpTypes, Cache) ->
- {TempRecords1, NewCache} =
+process_opaque_types0(TempRecords0, TempExpTypes) ->
+ Cache = erl_types:cache__new(),
+ {TempRecords1, Cache1} =
process_opaque_types(TempRecords0, TempExpTypes, Cache),
- process_opaque_types(TempRecords1, TempExpTypes, NewCache).
+ {TempRecords, _NewCache} =
+ process_opaque_types(TempRecords1, TempExpTypes, Cache1),
+ TempRecords.
process_opaque_types(TempRecords, TempExpTypes, Cache) ->
VarTable = erl_types:var_table__new(),
@@ -380,7 +381,8 @@ process_opaque_types(TempRecords, TempExpTypes, Cache) ->
{dict:from_list(TempRecordList), NewCache}.
%% dict:map(ModuleFun, TempRecords).
-check_record_fields(Records, TempExpTypes, Cache) ->
+check_record_fields(Records, TempExpTypes) ->
+ Cache = erl_types:cache__new(),
VarTable = erl_types:var_table__new(),
CheckFun =
fun({Module, Element}, C0) ->
@@ -412,7 +414,8 @@ check_record_fields(Records, TempExpTypes, Cache) ->
end,
lists:foldl(ElemFun, C0, dict:to_list(Element))
end,
- lists:foldl(CheckFun, Cache, dict:to_list(Records)).
+ _NewCache = lists:foldl(CheckFun, Cache, dict:to_list(Records)),
+ ok.
msg_with_position(Fun, FileLine) ->
try Fun()