Просмотр исходного кода

* fixed version of r11719 (faster parsing of units with lots of declarations
in many different type blocks)

git-svn-id: trunk@11722 -

Jonas Maebe 17 лет назад
Родитель
Сommit
156acf3817
3 измененных файлов с 37 добавлено и 8 удалено
  1. 17 4
      compiler/pdecl.pas
  2. 15 4
      compiler/symbase.pas
  3. 5 0
      compiler/symtable.pas

+ 17 - 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;
@@ -463,6 +472,8 @@ implementation
                     { we can ignore the result   }
                     { the definition is modified }
                     object_dec(orgtypename,nil,nil,tobjectdef(ttypesym(sym).typedef));
+                    { since the definition is modified, there may be new forwarddefs }
+                    symtablestack.top.forwardchecksyms.add(sym);
                     newtype:=ttypesym(sym);
                     hdef:=newtype.typedef;
                   end
@@ -591,7 +602,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;
 
@@ -308,6 +317,8 @@ implementation
       begin
         if sym.Owner<>self then
           internalerror(200611121);
+        if (sym.typ in [typesym,fieldvarsym]) then
+          forwardchecksyms.remove(sym);
         SymList.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;