diff options
author | Hans Bolinder <[email protected]> | 2016-12-19 10:02:12 +0100 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2017-01-11 09:34:59 +0100 |
commit | 7f3b77274958b62523e83ab2b37ad29ec9a6cf3c (patch) | |
tree | 47276a031c0210ae2f533b47962962042ec854d7 | |
parent | 2bcf8a6159e3b370739b835b52b95ff73c54776f (diff) | |
download | otp-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.erl | 16 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_utils.erl | 33 |
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() |