* 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 -
This commit is contained in:
Jonas Maebe 2008-09-07 12:24:57 +00:00
parent bc9e7c5580
commit 632abdace8
3 changed files with 35 additions and 8 deletions

View File

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

View File

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

View File

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