Browse Source

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 -
svenbarth 12 years ago
parent
commit
cc5a108cca
3 changed files with 35 additions and 20 deletions
  1. 19 13
      compiler/defcmp.pas
  2. 3 1
      compiler/pgenutil.pas
  3. 13 6
      compiler/symdef.pas

+ 19 - 13
compiler/defcmp.pas

@@ -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
-               internalerror(2012091301);
+             if assigned(tstoreddef(def_from).genericparas) xor
+                 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
-                   internalerror(2012091302);
-                 symfrom:=ttypesym(tstoreddef(def_from).genericparas[i]);
-                 symto:=ttypesym(tstoreddef(def_to).genericparas[i]);
-                 if not (symfrom.typ=typesym) or not (symto.typ=typesym) then
-                   internalerror(2012121401);
-                 if not equal_defs(ttypesym(symfrom).typedef,ttypesym(symto).typedef) then
-                   diff:=true;
-                 if diff then
-                   break;
+                 if tstoreddef(def_from).genericparas.count<>tstoreddef(def_to).genericparas.count then
+                   internalerror(2012091301);
+                 for i:=0 to tstoreddef(def_from).genericparas.count-1 do
+                   begin
+                     if tstoreddef(def_from).genericparas.nameofindex(i)<>tstoreddef(def_to).genericparas.nameofindex(i) then
+                       internalerror(2012091302);
+                     symfrom:=ttypesym(tstoreddef(def_from).genericparas[i]);
+                     symto:=ttypesym(tstoreddef(def_to).genericparas[i]);
+                     if not (symfrom.typ=typesym) or not (symto.typ=typesym) then
+                       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

+ 3 - 1
compiler/pgenutil.pas

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

+ 13 - 6
compiler/symdef.pas

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