From 632abdace8b5931c7be06681b74a21f9c3f60f53 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 7 Sep 2008 12:24:57 +0000 Subject: [PATCH] * keep the syms that need to be checked for forward definitions in a separate list, so that procsyms, constsym, varsyms etc are not checked and so that every sym is checked only once (rather than at the end of every type block). This makes parsing units with lots of declarations much faster (e.g., compiling MacOSAll is now 2 to 3 times faster) git-svn-id: trunk@11719 - --- compiler/pdecl.pas | 19 +++++++++++++++---- compiler/symbase.pas | 19 +++++++++++++++---- compiler/symtable.pas | 5 +++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/compiler/pdecl.pas b/compiler/pdecl.pas index 1a99d2ae02..d6a31c6628 100644 --- a/compiler/pdecl.pas +++ b/compiler/pdecl.pas @@ -293,7 +293,7 @@ implementation fieldvarsym : pd:=tfieldvarsym(p).vardef else - exit; + internalerror(2008090702); end; repeat again:=false; @@ -346,7 +346,11 @@ implementation end; end; recorddef : - trecorddef(pd).symtable.SymList.ForEachCall(@resolve_type_forward,nil); + begin + trecorddef(pd).symtable.forwardchecksyms.ForEachCall(@resolve_type_forward,nil); + { don't free, may still be reused } + trecorddef(pd).symtable.forwardchecksyms.clear; + end; objectdef : begin if not(m_fpc in current_settings.modeswitches) and @@ -362,7 +366,12 @@ implementation check objectdefs in objects/records, because these can't exist (anonymous objects aren't allowed) } if not(tsym(p).owner.symtabletype in [ObjectSymtable,recordsymtable]) then - tobjectdef(pd).symtable.SymList.ForEachCall(@resolve_type_forward,nil); + begin + tobjectdef(pd).symtable.forwardchecksyms.ForEachCall(@resolve_type_forward,nil); + { don't free, may still be reused } + tobjectdef(pd).symtable.forwardchecksyms.clear; + end; + end; end; end; @@ -591,7 +600,9 @@ implementation generictypelist.free; until token<>_ID; typecanbeforward:=false; - symtablestack.top.SymList.ForEachCall(@resolve_type_forward,nil); + symtablestack.top.forwardchecksyms.ForEachCall(@resolve_type_forward,nil); + { don't free, may still be reused } + symtablestack.top.forwardchecksyms.clear; block_type:=old_block_type; end; diff --git a/compiler/symbase.pas b/compiler/symbase.pas index 4b4d04d982..6ca9d6985e 100644 --- a/compiler/symbase.pas +++ b/compiler/symbase.pas @@ -92,6 +92,7 @@ interface realname : pshortstring; DefList : TFPObjectList; SymList : TFPHashObjectList; + forwardchecksyms : TFPObjectList; defowner : TDefEntry; { for records and objects } moduleid : longint; refcount : smallint; @@ -214,11 +215,13 @@ implementation name:=nil; realname:=nil; end; - symtabletype:=abstracTSymtable; + symtabletype:=abstractsymtable; symtablelevel:=0; defowner:=nil; DefList:=TFPObjectList.Create(true); SymList:=TFPHashObjectList.Create(true); + { the syms are owned by symlist, so don't free } + forwardchecksyms:=TFPObjectList.Create(false); refcount:=1; end; @@ -230,9 +233,11 @@ implementation exit; Clear; DefList.Free; - { SymList can already be disposed or set to nil for withsymtable } - if assigned(SymList) then - SymList.Free; + { SymList can already be disposed or set to nil for withsymtable, } + { but in that case Free does nothing } + SymList.Free; + forwardchecksyms.free; + stringdispose(name); stringdispose(realname); end; @@ -264,6 +269,7 @@ implementation i : integer; begin SymList.Clear; + forwardchecksyms.clear; { Prevent recursive calls between TDef.destroy and TSymtable.Remove } if DefList.OwnsObjects then begin @@ -300,6 +306,9 @@ implementation sym.ChangeOwnerAndName(SymList,Copy(sym.realname,2,255)) else sym.ChangeOwnerAndName(SymList,Upper(sym.realname)); + { keep track of syms whose type may need forward resolving later on } + if (sym.typ in [typesym,fieldvarsym]) then + forwardchecksyms.add(sym); sym.Owner:=self; end; @@ -309,6 +318,8 @@ implementation if sym.Owner<>self then internalerror(200611121); SymList.Remove(sym); + if (sym.typ in [typesym,fieldvarsym]) then + forwardchecksyms.remove(sym); end; diff --git a/compiler/symtable.pas b/compiler/symtable.pas index 2ba6d3868e..9b5e431bfa 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -1060,6 +1060,11 @@ implementation def:=TDef(unionst.DefList[i]); def.ChangeOwner(self); end; + { add the types that may need to be forward-checked } + forwardchecksyms.capacity:=forwardchecksyms.capacity+unionst.forwardchecksyms.count; + for i:=0 to unionst.forwardchecksyms.count-1 do + forwardchecksyms.add(tsym(unionst.forwardchecksyms[i])); + unionst.forwardchecksyms.clear; _datasize:=storesize; fieldalignment:=storealign; end;