From 8784dbc095442790a2f24cb675fdc67d1fe2d08f Mon Sep 17 00:00:00 2001 From: Rika Ichinose <rrunewalsh@gmail.com> Date: Thu, 21 Apr 2022 00:47:04 +0300 Subject: [PATCH] Outline freeing TFPList with disposing its items into TFPList.FreeAndNilDisposing. --- compiler/cclasses.pas | 23 +++++++++++++++++++++++ compiler/globals.pas | 35 ++--------------------------------- compiler/pgentype.pas | 6 +----- compiler/psub.pas | 9 +-------- compiler/symdef.pas | 10 +--------- compiler/symtable.pas | 32 +------------------------------- 6 files changed, 29 insertions(+), 86 deletions(-) diff --git a/compiler/cclasses.pas b/compiler/cclasses.pas index d3f8e32cc6..f01bb0d36c 100644 --- a/compiler/cclasses.pas +++ b/compiler/cclasses.pas @@ -116,6 +116,9 @@ type { FreeAndNil the list, and its items as TObjects. } class procedure FreeAndNilObjects(var Lst: TFPList); static; + + { FreeAndNil the list, and dispose() its items. 'ItemType' is TypeInfo() of items. } + class procedure FreeAndNilDisposing(var Lst: TFPList; ItemType: Pointer); static; end; @@ -1058,6 +1061,26 @@ begin Lst := nil; end; +procedure fpc_finalize(data, typeinfo: pointer); external; + +class procedure TFPList.FreeAndNilDisposing(var Lst: TFPList; ItemType: Pointer); +var + Lp: PPointer; + I: SizeInt; +begin + if not Assigned(Lst) then + exit; + Lp := Lst.FList; + for I := 0 to Lst.Count-1 do + if Assigned(Lp[I]) then + begin + fpc_finalize(Lp[I],ItemType); + FreeMem(Lp[I]); + end; + Lst.Free; + Lst := nil; +end; + {***************************************************************************** TFPObjectList (Copied from rtl/objpas/classes/lists.inc) diff --git a/compiler/globals.pas b/compiler/globals.pas index 1b5ef51248..750a1c54c6 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -1639,15 +1639,6 @@ implementation initdoneprocs : TFPList = nil; - procedure allocinitdoneprocs; - begin - { Avoid double initialization } - if assigned(initdoneprocs) then - exit; - initdoneprocs:=tfplist.create; - end; - - procedure register_initdone_proc(init,done:tprocedure); var entry : pinitdoneentry; @@ -1655,14 +1646,7 @@ implementation new(entry); entry^.init:=init; entry^.done:=done; - { Do not rely on the fact that - globals unit initialization code - has already been executed. - Unit initialization order is too - uncertian for that. PM } - if not assigned(initdoneprocs) then - allocinitdoneprocs; - initdoneprocs.add(entry); + TFPList.AddOnDemand(initdoneprocs,entry); end; @@ -1692,20 +1676,6 @@ implementation end; - procedure freeinitdoneprocs; - var - i : longint; - begin - if not assigned(initdoneprocs) then - exit; - for i:=0 to initdoneprocs.count-1 do - dispose(pinitdoneentry(initdoneprocs[i])); - initdoneprocs.free; - { Reset variable, to be on the safe side } - initdoneprocs:=nil; - end; - - procedure DoneGlobals; begin calldoneprocs; @@ -1810,12 +1780,11 @@ implementation end; initialization - allocinitdoneprocs; {$ifdef LLVM} cgbackend:=cg_llvm; {$else} cgbackend:=cg_fpc; {$endif} finalization - freeinitdoneprocs; + tfplist.FreeAndNilDisposing(initdoneprocs,TypeInfo(tinitdoneentry)); end. diff --git a/compiler/pgentype.pas b/compiler/pgentype.pas index 9354fe2f50..d7acba6a72 100644 --- a/compiler/pgentype.pas +++ b/compiler/pgentype.pas @@ -65,13 +65,9 @@ begin end; destructor tspecializationcontext.destroy; -var - i : longint; begin paramlist.free; - for i:=0 to poslist.count-1 do - dispose(pfileposinfo(poslist[i])); - poslist.free; + tfplist.FreeAndNilDisposing(poslist,TypeInfo(tfileposinfo)); inherited destroy; end; diff --git a/compiler/psub.pas b/compiler/psub.pas index ecb67441fd..06bca7299d 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -684,15 +684,8 @@ implementation ****************************************************************************} destructor tcgprocinfo.destroy; - var - i : longint; begin - if assigned(tempinfo_flags_map) then - begin - for i:=0 to tempinfo_flags_map.count-1 do - dispose(ptempinfo_flags_entry(tempinfo_flags_map[i])); - tempinfo_flags_map.free; - end; + TFPList.FreeAndNilDisposing(tempinfo_flags_map,TypeInfo(ttempinfo_flags_entry)); code.free; inherited destroy; end; diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 2da87ff372..37ae0bcf96 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -8024,8 +8024,6 @@ implementation destructor tobjectdef.destroy; - var - i: longint; begin if assigned(symtable) then begin @@ -8044,13 +8042,7 @@ implementation dispose(iidguid); iidguid:=nil; end; - if assigned(vmtentries) then - begin - for i:=0 to vmtentries.count-1 do - dispose(pvmtentry(vmtentries[i])); - vmtentries.free; - vmtentries:=nil; - end; + TFPList.FreeAndNilDisposing(vmtentries,TypeInfo(tvmtentry)); if assigned(vmcallstaticinfo) then begin freemem(vmcallstaticinfo); diff --git a/compiler/symtable.pas b/compiler/symtable.pas index 6c62f71f38..33213cd20c 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -1211,29 +1211,8 @@ implementation destructor tabstractrecordsymtable.destroy; - - { for some reason a compiler built with 3.3.1 fails building the libxml2 - package if the below define is not defined and thus the code snippet is - part of the destructor itself and not a nested procedure; until that bug - is fixed this is used as a workaround :/ } -{$define codegen_workaround} -{$ifdef codegen_workaround} - procedure free_mop_list(mop:tmanagementoperator); - var - i : longint; - begin - if assigned(mop_list[mop]) then - for i:=0 to mop_list[mop].count-1 do - dispose(pmanagementoperator_offset_entry(mop_list[mop][i])); - mop_list[mop].free; - end; -{$endif codegen_workaround} - var mop : tmanagementoperator; -{$ifndef codegen_workaround} - i : longint; -{$endif codegen_workaround} begin if refcount>1 then exit; @@ -1241,16 +1220,7 @@ implementation fllvmst.free; {$endif llvm} for mop:=low(tmanagementoperator) to high(tmanagementoperator) do - begin -{$ifdef codegen_workaround} - free_mop_list(mop); -{$else codegen_workaround} - if assigned(mop_list[mop]) then - for i:=0 to mop_list[mop].count-1 do - dispose(pmanagementoperator_offset_entry(mop_list[mop][i])); - mop_list[mop].free; -{$endif codegen_workaround} - end; + TFPList.FreeAndNilDisposing(mop_list[mop],TypeInfo(tmanagementoperator_offset_entry)); inherited destroy; end;