Browse Source

* 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 -

Jonas Maebe 17 years ago
parent
commit
632abdace8
3 changed files with 35 additions and 8 deletions
  1. 15 4
      compiler/pdecl.pas
  2. 15 4
      compiler/symbase.pas
  3. 5 0
      compiler/symtable.pas

+ 15 - 4
compiler/pdecl.pas

@@ -293,7 +293,7 @@ implementation
            fieldvarsym :
            fieldvarsym :
              pd:=tfieldvarsym(p).vardef
              pd:=tfieldvarsym(p).vardef
            else
            else
-             exit;
+             internalerror(2008090702);
          end;
          end;
          repeat
          repeat
            again:=false;
            again:=false;
@@ -346,7 +346,11 @@ implementation
                   end;
                   end;
                end;
                end;
              recorddef :
              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 :
              objectdef :
                begin
                begin
                  if not(m_fpc in current_settings.modeswitches) and
                  if not(m_fpc in current_settings.modeswitches) and
@@ -362,7 +366,12 @@ implementation
                       check objectdefs in objects/records, because these
                       check objectdefs in objects/records, because these
                       can't exist (anonymous objects aren't allowed) }
                       can't exist (anonymous objects aren't allowed) }
                     if not(tsym(p).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
                     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;
                end;
           end;
           end;
@@ -591,7 +600,9 @@ implementation
              generictypelist.free;
              generictypelist.free;
          until token<>_ID;
          until token<>_ID;
          typecanbeforward:=false;
          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;
          block_type:=old_block_type;
       end;
       end;
 
 

+ 15 - 4
compiler/symbase.pas

@@ -92,6 +92,7 @@ interface
           realname  : pshortstring;
           realname  : pshortstring;
           DefList   : TFPObjectList;
           DefList   : TFPObjectList;
           SymList   : TFPHashObjectList;
           SymList   : TFPHashObjectList;
+          forwardchecksyms : TFPObjectList;
           defowner  : TDefEntry; { for records and objects }
           defowner  : TDefEntry; { for records and objects }
           moduleid  : longint;
           moduleid  : longint;
           refcount  : smallint;
           refcount  : smallint;
@@ -214,11 +215,13 @@ implementation
              name:=nil;
              name:=nil;
              realname:=nil;
              realname:=nil;
            end;
            end;
-         symtabletype:=abstracTSymtable;
+         symtabletype:=abstractsymtable;
          symtablelevel:=0;
          symtablelevel:=0;
          defowner:=nil;
          defowner:=nil;
          DefList:=TFPObjectList.Create(true);
          DefList:=TFPObjectList.Create(true);
          SymList:=TFPHashObjectList.Create(true);
          SymList:=TFPHashObjectList.Create(true);
+         { the syms are owned by symlist, so don't free }
+         forwardchecksyms:=TFPObjectList.Create(false);
          refcount:=1;
          refcount:=1;
       end;
       end;
 
 
@@ -230,9 +233,11 @@ implementation
           exit;
           exit;
         Clear;
         Clear;
         DefList.Free;
         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(name);
         stringdispose(realname);
         stringdispose(realname);
       end;
       end;
@@ -264,6 +269,7 @@ implementation
         i : integer;
         i : integer;
       begin
       begin
          SymList.Clear;
          SymList.Clear;
+         forwardchecksyms.clear;
          { Prevent recursive calls between TDef.destroy and TSymtable.Remove }
          { Prevent recursive calls between TDef.destroy and TSymtable.Remove }
          if DefList.OwnsObjects then
          if DefList.OwnsObjects then
            begin
            begin
@@ -300,6 +306,9 @@ implementation
            sym.ChangeOwnerAndName(SymList,Copy(sym.realname,2,255))
            sym.ChangeOwnerAndName(SymList,Copy(sym.realname,2,255))
          else
          else
            sym.ChangeOwnerAndName(SymList,Upper(sym.realname));
            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;
          sym.Owner:=self;
       end;
       end;
 
 
@@ -309,6 +318,8 @@ implementation
         if sym.Owner<>self then
         if sym.Owner<>self then
           internalerror(200611121);
           internalerror(200611121);
         SymList.Remove(sym);
         SymList.Remove(sym);
+        if (sym.typ in [typesym,fieldvarsym]) then
+          forwardchecksyms.remove(sym);
       end;
       end;
 
 
 
 

+ 5 - 0
compiler/symtable.pas

@@ -1060,6 +1060,11 @@ implementation
             def:=TDef(unionst.DefList[i]);
             def:=TDef(unionst.DefList[i]);
             def.ChangeOwner(self);
             def.ChangeOwner(self);
           end;
           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;
         _datasize:=storesize;
         fieldalignment:=storealign;
         fieldalignment:=storealign;
       end;
       end;