Bläddra i källkod

* 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 år sedan
förälder
incheckning
632abdace8
3 ändrade filer med 35 tillägg och 8 borttagningar
  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;