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 :
              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;
 

+ 15 - 4
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;
 
 

+ 5 - 0
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;