Browse Source

* fix interface vtbl optimization
* replace ugly pointer construct of ioffset()

peter 20 years ago
parent
commit
bb32ee0457
4 changed files with 84 additions and 49 deletions
  1. 6 2
      compiler/ncgcnv.pas
  2. 31 18
      compiler/nobj.pas
  3. 6 2
      compiler/ptconst.pas
  4. 41 27
      compiler/symdef.pas

+ 6 - 2
compiler/ncgcnv.pas

@@ -471,7 +471,7 @@ interface
                 begin
                    cg.a_op_const_reg(exprasmlist,OP_ADD,OS_ADDR,
                      hd.implementedinterfaces.ioffsets(
-                       hd.implementedinterfaces.searchintf(resulttype.def))^,location.register);
+                       hd.implementedinterfaces.searchintf(resulttype.def)),location.register);
                    break;
                 end;
               hd:=hd.childof;
@@ -567,7 +567,11 @@ end.
 
 {
   $Log$
-  Revision 1.71  2004-12-26 20:09:35  peter
+  Revision 1.72  2005-01-09 15:05:29  peter
+    * fix interface vtbl optimization
+    * replace ugly pointer construct of ioffset()
+
+  Revision 1.71  2004/12/26 20:09:35  peter
     * typecast float to non-float needs a move to memory
 
   Revision 1.70  2004/12/25 12:29:08  florian

+ 31 - 18
compiler/nobj.pas

@@ -889,7 +889,7 @@ implementation
               tostr(i)+'_$_'+
               implintf.implprocs(intfindex,i).mangledname);
             { create wrapper code }
-            cgintfwrapper(rawcode,implintf.implprocs(intfindex,i),tmps,implintf.ioffsets(intfindex)^);
+            cgintfwrapper(rawcode,implintf.implprocs(intfindex,i),tmps,implintf.ioffsets(intfindex));
             { create reference }
             rawdata.concat(Tai_const.Createname(tmps,AT_FUNCTION,0));
           end;
@@ -927,7 +927,7 @@ implementation
         { VTable }
         dataSegment.concat(Tai_const.Createname(gintfgetvtbllabelname(contintfindex),AT_DATA,0));
         { IOffset field }
-        dataSegment.concat(Tai_const.Create_32bit(implintf.ioffsets(contintfindex)^));
+        dataSegment.concat(Tai_const.Create_32bit(implintf.ioffsets(contintfindex)));
         { IIDStr }
         objectlibrary.getdatalabel(tmplabel);
         rawdata.concat(tai_align.create(const_align(sizeof(aint))));
@@ -956,9 +956,7 @@ implementation
         max: longint;
         equals: pequals;
         compats: pcompintfs;
-        i: longint;
-        j: longint;
-        w: longint;
+        w,i,j,k: longint;
         cij: boolean;
         cji: boolean;
       begin
@@ -1007,15 +1005,27 @@ implementation
                   end;
               end;
           end;
+        { Reset, no replacements by default }
         for i:=1 to max do
-          begin
-            if compats^[i].compintf<>0 then
-              implvtbl[i]:=compats^[i].compintf
-            else if equals^[i]<>0 then
-              implvtbl[i]:=equals^[i]
-            else
-              implvtbl[i]:=i;
-          end;
+          implvtbl[i]:=i;
+        { Replace vtbls when equal or compat, repeat
+          until there are no replacements possible anymore. This is
+          needed for the cases like:
+            First loop: 2->3, 3->1
+            Second loop: 2->1 (because 3 was replaced with 1)
+        }
+        repeat
+          k:=0;
+          for i:=1 to max do
+            begin
+              if compats^[implvtbl[i]].compintf<>0 then
+                implvtbl[i]:=compats^[implvtbl[i]].compintf
+              else if equals^[implvtbl[i]]<>0 then
+                implvtbl[i]:=equals^[implvtbl[i]]
+              else
+                inc(k);
+            end;
+        until k=max;
         freemem(compats,sizeof(tcompintfentry)*max);
         freemem(equals,sizeof(longint)*max);
       end;
@@ -1045,7 +1055,7 @@ implementation
                 with tobjectsymtable(_class.symtable) do
                   begin
                     datasize:=align(datasize,min(sizeof(aint),fieldalignment));
-                    _class.implementedinterfaces.ioffsets(i)^:=datasize;
+                    _class.implementedinterfaces.setioffsets(i,datasize);
                     inc(datasize,sizeof(aint));
                   end;
                 { write vtbl }
@@ -1055,9 +1065,8 @@ implementation
         { second pass: for fill interfacetable and remained ioffsets }
         for i:=1 to max do
           begin
-            if i<>impintfindexes[i] then { why execute x:=x ? }
-              with _class.implementedinterfaces do
-                ioffsets(i)^:=ioffsets(impintfindexes[i])^;
+            if impintfindexes[i]<>i then
+              _class.implementedinterfaces.setioffsets(i,_class.implementedinterfaces.ioffsets(impintfindexes[i]));
             gintfgenentry(i,impintfindexes[i],rawdata);
           end;
         dataSegment.concatlist(rawdata);
@@ -1405,7 +1414,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.84  2004-12-26 20:16:44  peter
+  Revision 1.85  2005-01-09 15:05:29  peter
+    * fix interface vtbl optimization
+    * replace ugly pointer construct of ioffset()
+
+  Revision 1.84  2004/12/26 20:16:44  peter
     * also compare procoptions and proctype when searching interface
       implementations
 

+ 6 - 2
compiler/ptconst.pas

@@ -845,7 +845,7 @@ implementation
                       p.free;
                       if string2guid(s,tmpguid) then
                         begin
-                          curconstSegment.concat(Tai_const.Create_32bit(tmpguid.D1));
+                          curconstSegment.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
                           curconstSegment.concat(Tai_const.Create_16bit(tmpguid.D2));
                           curconstSegment.concat(Tai_const.Create_16bit(tmpguid.D3));
                           for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
@@ -1081,7 +1081,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.98  2005-01-08 14:05:31  florian
+  Revision 1.99  2005-01-09 15:05:29  peter
+    * fix interface vtbl optimization
+    * replace ugly pointer construct of ioffset()
+
+  Revision 1.98  2005/01/08 14:05:31  florian
     * typed dyn. array constants can be only nil pointer
 
   Revision 1.97  2004/12/05 12:28:11  peter

+ 41 - 27
compiler/symdef.pas

@@ -246,9 +246,21 @@ interface
        end;
 
        tprocdef = class;
-
+       tobjectdef = class;
        timplementedinterfaces = class;
 
+       timplintfentry = class(TNamedIndexItem)
+         intf         : tobjectdef;
+         intfderef    : tderef;
+         ioffset      : longint;
+         implintf     : longint;
+         namemappings : tdictionary;
+         procdefs     : TIndexArray;
+         constructor create(aintf: tobjectdef);
+         constructor create_deref(const d:tderef);
+         destructor  destroy; override;
+       end;
+
        tobjectdef = class(tabstractrecorddef)
        private
 {$ifdef GDB}
@@ -324,14 +336,15 @@ interface
           function  count: longint;
           function  interfaces(intfindex: longint): tobjectdef;
           function  interfacesderef(intfindex: longint): tderef;
-          function  ioffsets(intfindex: longint): plongint;
+          function  ioffsets(intfindex: longint): longint;
+          procedure setioffsets(intfindex,iofs:longint);
           function  searchintf(def: tdef): longint;
           procedure addintf(def: tdef);
 
           procedure buildderef;
           procedure deref;
           { add interface reference loaded from ppu }
-          procedure addintf_deref(const d:tderef);
+          procedure addintf_deref(const d:tderef;iofs:longint);
 
           procedure clearmappings;
           procedure addmappings(intfindex: longint; const name, newname: string);
@@ -1854,7 +1867,7 @@ implementation
          end;
 {$ifdef cpurequiresproperalignment}
          rttilist.concat(Tai_align.Create(4));
-{$endif cpurequiresproperalignment}          
+{$endif cpurequiresproperalignment}
          rttiList.concat(Tai_const.Create_32bit(min));
          rttiList.concat(Tai_const.Create_32bit(max));
          if assigned(basedef) then
@@ -2023,7 +2036,7 @@ implementation
           rttiList.concat(Tai_const.Create_8bit(byte(trans[typ])));
 {$ifdef cpurequiresproperalignment}
          rttilist.concat(Tai_align.Create(4));
-{$endif cpurequiresproperalignment}          
+{$endif cpurequiresproperalignment}
           rttiList.concat(Tai_const.Create_32bit(longint(low)));
           rttiList.concat(Tai_const.Create_32bit(longint(high)));
         end;
@@ -4877,8 +4890,7 @@ implementation
              for i:=1 to implintfcount do
                begin
                   ppufile.getderef(d);
-                  implementedinterfaces.addintf_deref(d);
-                  implementedinterfaces.ioffsets(i)^:=ppufile.getlongint;
+                  implementedinterfaces.addintf_deref(d,ppufile.getlongint);
                end;
            end
          else
@@ -4973,7 +4985,7 @@ implementation
               for i:=1 to implintfcount do
                 begin
                    ppufile.putderef(implementedinterfaces.interfacesderef(i));
-                   ppufile.putlongint(implementedinterfaces.ioffsets(i)^);
+                   ppufile.putlongint(implementedinterfaces.ioffsets(i));
                 end;
            end;
 
@@ -5932,23 +5944,11 @@ implementation
       end;
 
 
-    type
-      timplintfentry = class(TNamedIndexItem)
-        intf: tobjectdef;
-        intfderef : tderef;
-        ioffs: longint;
-        namemappings: tdictionary;
-        procdefs: TIndexArray;
-        constructor create(aintf: tobjectdef);
-        constructor create_deref(const d:tderef);
-        destructor  destroy; override;
-      end;
-
     constructor timplintfentry.create(aintf: tobjectdef);
       begin
         inherited create;
         intf:=aintf;
-        ioffs:=-1;
+        ioffset:=-1;
         namemappings:=nil;
         procdefs:=nil;
       end;
@@ -5959,7 +5959,7 @@ implementation
         inherited create;
         intf:=nil;
         intfderef:=d;
-        ioffs:=-1;
+        ioffset:=-1;
         namemappings:=nil;
         procdefs:=nil;
       end;
@@ -6008,10 +6008,16 @@ implementation
         interfacesderef:=timplintfentry(finterfaces.search(intfindex)).intfderef;
       end;
 
-    function  timplementedinterfaces.ioffsets(intfindex: longint): plongint;
+    function  timplementedinterfaces.ioffsets(intfindex: longint): longint;
       begin
         checkindex(intfindex);
-        ioffsets:=@timplintfentry(finterfaces.search(intfindex)).ioffs;
+        ioffsets:=timplintfentry(finterfaces.search(intfindex)).ioffset;
+      end;
+
+    procedure timplementedinterfaces.setioffsets(intfindex,iofs:longint);
+      begin
+        checkindex(intfindex);
+        timplintfentry(finterfaces.search(intfindex)).ioffset:=iofs;
       end;
 
     function  timplementedinterfaces.searchintf(def: tdef): longint;
@@ -6046,9 +6052,13 @@ implementation
             intf:=tobjectdef(intfderef.resolve);
       end;
 
-    procedure timplementedinterfaces.addintf_deref(const d:tderef);
+    procedure timplementedinterfaces.addintf_deref(const d:tderef;iofs:longint);
+      var
+        hintf : timplintfentry;
       begin
-        finterfaces.insert(timplintfentry.create_deref(d));
+        hintf:=timplintfentry.create_deref(d);
+        hintf.ioffset:=iofs;
+        finterfaces.insert(hintf);
       end;
 
     procedure timplementedinterfaces.addintf(def: tdef);
@@ -6321,7 +6331,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.287  2005-01-03 17:55:57  florian
+  Revision 1.288  2005-01-09 15:05:29  peter
+    * fix interface vtbl optimization
+    * replace ugly pointer construct of ioffset()
+
+  Revision 1.287  2005/01/03 17:55:57  florian
     + first batch of patches to support tdef.getcopy fully
 
   Revision 1.286  2004/12/30 14:36:29  florian