Allocate the list for generic parameters in tstoreddef only on demand as most defs won't contain generic parameters anyway (avoids a little bit of runtime and memory overhead per def).

symdef.pas, tstoreddef:
  + comment that the list is allocated on demand (and thus should be checked for Nil)
  + fillgenericparas: create the list when adding at least one generic parameter symbol
  - create & ppuload: don't create list instance anymore
  + is_generic & is_specialization: check whether the list is assigned
defcmp.pas, compare_defs_ext:
  + check whether "genericparas" list is assigned
pgenutil.pas:
  + check_generic_constraints: check whether "genericparas" is assigned
  + insert_generic_parameter_types: create list before adding generic parameters

git-svn-id: trunk@24627 -
This commit is contained in:
svenbarth 2013-05-29 07:50:49 +00:00
parent 4ca7e66661
commit cc5a108cca
3 changed files with 35 additions and 20 deletions

View File

@ -271,21 +271,27 @@ implementation
(df_specialization in def_to.defoptions) and (df_specialization in def_to.defoptions) and
(tstoreddef(def_from).genericdef=tstoreddef(def_to).genericdef) then (tstoreddef(def_from).genericdef=tstoreddef(def_to).genericdef) then
begin begin
if tstoreddef(def_from).genericparas.count<>tstoreddef(def_to).genericparas.count then if assigned(tstoreddef(def_from).genericparas) xor
internalerror(2012091301); assigned(tstoreddef(def_to).genericparas) then
internalerror(2013030901);
diff:=false; diff:=false;
for i:=0 to tstoreddef(def_from).genericparas.count-1 do if assigned(tstoreddef(def_from).genericparas) then
begin begin
if tstoreddef(def_from).genericparas.nameofindex(i)<>tstoreddef(def_to).genericparas.nameofindex(i) then if tstoreddef(def_from).genericparas.count<>tstoreddef(def_to).genericparas.count then
internalerror(2012091302); internalerror(2012091301);
symfrom:=ttypesym(tstoreddef(def_from).genericparas[i]); for i:=0 to tstoreddef(def_from).genericparas.count-1 do
symto:=ttypesym(tstoreddef(def_to).genericparas[i]); begin
if not (symfrom.typ=typesym) or not (symto.typ=typesym) then if tstoreddef(def_from).genericparas.nameofindex(i)<>tstoreddef(def_to).genericparas.nameofindex(i) then
internalerror(2012121401); internalerror(2012091302);
if not equal_defs(ttypesym(symfrom).typedef,ttypesym(symto).typedef) then symfrom:=ttypesym(tstoreddef(def_from).genericparas[i]);
diff:=true; symto:=ttypesym(tstoreddef(def_to).genericparas[i]);
if diff then if not (symfrom.typ=typesym) or not (symto.typ=typesym) then
break; internalerror(2012121401);
if not equal_defs(ttypesym(symfrom).typedef,ttypesym(symto).typedef) then
diff:=true;
if diff then
break;
end;
end; end;
if not diff then if not diff then
begin begin

View File

@ -112,7 +112,7 @@ uses
begin begin
{ check whether the given specialization parameters fit to the eventual { check whether the given specialization parameters fit to the eventual
constraints of the generic } constraints of the generic }
if genericdef.genericparas.count=0 then if not assigned(genericdef.genericparas) or (genericdef.genericparas.count=0) then
internalerror(2012101001); internalerror(2012101001);
if genericdef.genericparas.count<>paradeflist.count then if genericdef.genericparas.count<>paradeflist.count then
internalerror(2012101002); internalerror(2012101002);
@ -1039,6 +1039,8 @@ uses
internalerror(201101020); internalerror(201101020);
end; end;
if (genericlist.count>0) and not assigned(def.genericparas) then
def.genericparas:=tfphashobjectlist.create(false);
for i:=0 to genericlist.count-1 do for i:=0 to genericlist.count-1 do
begin begin
generictype:=ttypesym(genericlist[i]); generictype:=ttypesym(genericlist[i]);

View File

@ -66,7 +66,8 @@ interface
genericdefderef : tderef; genericdefderef : tderef;
generictokenbuf : tdynamicarray; generictokenbuf : tdynamicarray;
{ this list contains references to the symbols that make up the { this list contains references to the symbols that make up the
generic parameters; the symbols are not owned by this list } generic parameters; the symbols are not owned by this list
Note: this list is allocated on demand! }
genericparas : tfphashobjectlist; genericparas : tfphashobjectlist;
constructor create(dt:tdeftyp); constructor create(dt:tdeftyp);
constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile); constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
@ -1388,7 +1389,11 @@ implementation
begin begin
sym:=tsym(symtable.symlist[i]); sym:=tsym(symtable.symlist[i]);
if sp_generic_para in sym.symoptions then if sp_generic_para in sym.symoptions then
genericparas.Add(sym.name,sym); begin
if not assigned(genericparas) then
genericparas:=tfphashobjectlist.create(false);
genericparas.Add(sym.name,sym);
end;
end; end;
end; end;
@ -1403,7 +1408,6 @@ implementation
{$endif} {$endif}
generictokenbuf:=nil; generictokenbuf:=nil;
genericdef:=nil; genericdef:=nil;
genericparas:=tfphashobjectlist.create(false);
{ Don't register forwarddefs, they are disposed at the { Don't register forwarddefs, they are disposed at the
end of an type block } end of an type block }
@ -1450,7 +1454,6 @@ implementation
buf : array[0..255] of byte; buf : array[0..255] of byte;
begin begin
inherited create(dt); inherited create(dt);
genericparas:=tfphashobjectlist.create(false);
DefId:=ppufile.getlongint; DefId:=ppufile.getlongint;
current_module.deflist[DefId]:=self; current_module.deflist[DefId]:=self;
{$ifdef EXTDEBUG} {$ifdef EXTDEBUG}
@ -1697,13 +1700,17 @@ implementation
function tstoreddef.is_generic: boolean; function tstoreddef.is_generic: boolean;
begin begin
result:=(genericparas.count>0) and (df_generic in defoptions); result:=assigned(genericparas) and
(genericparas.count>0) and
(df_generic in defoptions);
end; end;
function tstoreddef.is_specialization: boolean; function tstoreddef.is_specialization: boolean;
begin begin
result:=(genericparas.count>0) and (df_specialization in defoptions); result:=assigned(genericparas) and
(genericparas.count>0) and
(df_specialization in defoptions);
end; end;