Преглед на файлове

* record alignment splitted in fieldalignment and recordalignment,
the latter is used when this record is inserted in another record.

peter преди 21 години
родител
ревизия
2d8d788211
променени са 5 файла, в които са добавени 86 реда и са изтрити 87 реда
  1. 7 6
      compiler/nobj.pas
  2. 11 7
      compiler/pdecvar.pas
  3. 7 2
      compiler/ptype.pas
  4. 21 41
      compiler/symdef.pas
  5. 40 31
      compiler/symtable.pas

+ 7 - 6
compiler/nobj.pas

@@ -1007,12 +1007,9 @@ implementation
                 { allocate a pointer in the object memory }
                 with tobjectsymtable(_class.symtable) do
                   begin
-                    if (dataalignment>=pointer_size) then
-                      datasize:=align(datasize,dataalignment)
-                    else
-                      datasize:=align(datasize,pointer_size);
+                    datasize:=align(datasize,min(POINTER_SIZE,fieldalignment));
                     _class.implementedinterfaces.ioffsets(i)^:=datasize;
-                    datasize:=datasize+pointer_size;
+                    inc(datasize,POINTER_SIZE);
                   end;
                 { write vtbl }
                 gintfcreatevtbl(i,rawdata,rawcode);
@@ -1370,7 +1367,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.58  2004-01-21 14:22:00  florian
+  Revision 1.59  2004-01-28 20:30:18  peter
+    * record alignment splitted in fieldalignment and recordalignment,
+      the latter is used when this record is inserted in another record.
+
+  Revision 1.58  2004/01/21 14:22:00  florian
     + reintroduce implemented
 
   Revision 1.57  2003/12/08 22:34:24  peter

+ 11 - 7
compiler/pdecvar.pas

@@ -1073,7 +1073,7 @@ implementation
                 Uniondef.owner:=symtablestack.defowner.owner;
               registerdef:=true;
               startvarrecsize:=UnionSymtable.datasize;
-              startvarrecalign:=UnionSymtable.dataalignment;
+              startvarrecalign:=UnionSymtable.fieldalignment;
               symtablestack:=UnionSymtable;
               repeat
                 repeat
@@ -1096,10 +1096,10 @@ implementation
                 consume(_RKLAMMER);
                 { calculates maximal variant size }
                 maxsize:=max(maxsize,unionsymtable.datasize);
-                maxalignment:=max(maxalignment,unionsymtable.dataalignment);
+                maxalignment:=max(maxalignment,unionsymtable.fieldalignment);
                 { the items of the next variant are overlayed }
                 unionsymtable.datasize:=startvarrecsize;
-                unionsymtable.dataalignment:=startvarrecalign;
+                unionsymtable.fieldalignment:=startvarrecalign;
                 if (token<>_END) and (token<>_RKLAMMER) then
                   consume(_SEMICOLON)
                 else
@@ -1107,7 +1107,7 @@ implementation
               until (token=_END) or (token=_RKLAMMER);
               { at last set the record size to that of the biggest variant }
               unionsymtable.datasize:=maxsize;
-              unionsymtable.dataalignment:=maxalignment;
+              unionsymtable.fieldalignment:=maxalignment;
               uniontype.def:=uniondef;
               uniontype.sym:=nil;
               UnionSym:=tvarsym.create('$case',vs_value,uniontype);
@@ -1135,8 +1135,8 @@ implementation
               usedalign:=used_align(maxalignment,minalignment,maxalignment);
               offset:=align(trecordsymtable(symtablestack).datasize,usedalign);
               trecordsymtable(symtablestack).datasize:=offset+unionsymtable.datasize;
-              if maxalignment>trecordsymtable(symtablestack).dataalignment then
-                trecordsymtable(symtablestack).dataalignment:=maxalignment;
+              if maxalignment>trecordsymtable(symtablestack).fieldalignment then
+                trecordsymtable(symtablestack).fieldalignment:=maxalignment;
               Unionsymtable.Insert_in(trecordsymtable(symtablestack),offset);
               Unionsym.owner:=nil;
               unionsym.free;
@@ -1152,7 +1152,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.59  2003-12-10 16:37:01  peter
+  Revision 1.60  2004-01-28 20:30:18  peter
+    * record alignment splitted in fieldalignment and recordalignment,
+      the latter is used when this record is inserted in another record.
+
+  Revision 1.59  2003/12/10 16:37:01  peter
     * global property support for fpc modes
 
   Revision 1.58  2003/11/23 17:05:15  peter

+ 7 - 2
compiler/ptype.pas

@@ -244,7 +244,8 @@ implementation
          typecanbeforward:=storetypecanbeforward;
          current_object_option:=old_object_option;
          { may be scale record size to a size of n*4 ? }
-         trecordsymtable(symtablestack).datasize:=align(trecordsymtable(symtablestack).datasize,trecordsymtable(symtablestack).dataalignment);
+         trecordsymtable(symtablestack).datasize:=align(trecordsymtable(symtablestack).datasize,
+             trecordsymtable(symtablestack).fieldalignment);
          { restore symtable stack }
          symtablestack:=symtable.next;
       end;
@@ -643,7 +644,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.60  2003-10-21 18:16:13  peter
+  Revision 1.61  2004-01-28 20:30:18  peter
+    * record alignment splitted in fieldalignment and recordalignment,
+      the latter is used when this record is inserted in another record.
+
+  Revision 1.60  2003/10/21 18:16:13  peter
     * IncompatibleTypes() added that will include unit names when
       the typenames are the same
 

+ 21 - 41
compiler/symdef.pas

@@ -3047,9 +3047,9 @@ implementation
          { recordalign -1 means C record packing, that starts
            with an alignment of 1 }
          if aktalignment.recordalignmax=-1 then
-           trecordsymtable(symtable).dataalignment:=1
+           trecordsymtable(symtable).fieldalignment:=1
          else
-           trecordsymtable(symtable).dataalignment:=aktalignment.recordalignmax;
+           trecordsymtable(symtable).fieldalignment:=aktalignment.recordalignmax;
          isunion:=false;
       end;
 
@@ -3061,7 +3061,8 @@ implementation
          savesize:=ppufile.getlongint;
          symtable:=trecordsymtable.create;
          trecordsymtable(symtable).datasize:=ppufile.getlongint;
-         trecordsymtable(symtable).dataalignment:=ppufile.getbyte;
+         trecordsymtable(symtable).fieldalignment:=ppufile.getbyte;
+         trecordsymtable(symtable).recordalignment:=ppufile.getbyte;
          trecordsymtable(symtable).ppuload(ppufile);
          symtable.defowner:=self;
          isunion:=false;
@@ -3120,7 +3121,8 @@ implementation
          inherited ppuwritedef(ppufile);
          ppufile.putlongint(savesize);
          ppufile.putlongint(trecordsymtable(symtable).datasize);
-         ppufile.putbyte(trecordsymtable(symtable).dataalignment);
+         ppufile.putbyte(trecordsymtable(symtable).fieldalignment);
+         ppufile.putbyte(trecordsymtable(symtable).recordalignment);
          ppufile.writeentry(ibrecorddef);
          trecordsymtable(symtable).ppuwrite(ppufile);
       end;
@@ -3133,36 +3135,8 @@ implementation
 
 
     function trecorddef.alignment:longint;
-      var
-        l  : longint;
-        hp : tvarsym;
-      begin
-        { also check the first symbol for it's size, because a
-          packed record has dataalignment of 1, but the first
-          sym could be a longint which should be aligned on 4 bytes,
-          this is compatible with C record packing (PFV) }
-        hp:=tvarsym(symtable.symindex.first);
-        if assigned(hp) then
-         begin
-           if hp.vartype.def.deftype in [recorddef,arraydef] then
-            l:=hp.vartype.def.alignment
-           else
-            l:=hp.vartype.def.size;
-           if l>trecordsymtable(symtable).dataalignment then
-            begin
-              if l>=4 then
-               alignment:=4
-              else
-               if l>=2 then
-                alignment:=2
-              else
-               alignment:=1;
-            end
-           else
-            alignment:=trecordsymtable(symtable).dataalignment;
-         end
-        else
-         alignment:=trecordsymtable(symtable).dataalignment;
+      begin
+        alignment:=trecordsymtable(symtable).recordalignment;
       end;
 
 
@@ -4700,9 +4674,9 @@ implementation
         { recordalign -1 means C record packing, that starts
           with an alignment of 1 }
         if aktalignment.recordalignmax=-1 then
-         tobjectsymtable(symtable).dataalignment:=1
+         tobjectsymtable(symtable).fieldalignment:=1
         else
-         tobjectsymtable(symtable).dataalignment:=aktalignment.recordalignmax;
+         tobjectsymtable(symtable).fieldalignment:=aktalignment.recordalignmax;
         lastvtableindex:=0;
         set_parent(c);
         objname:=stringdup(upper(n));
@@ -4763,7 +4737,8 @@ implementation
 
          symtable:=tobjectsymtable.create(objrealname^);
          tobjectsymtable(symtable).datasize:=ppufile.getlongint;
-         tobjectsymtable(symtable).dataalignment:=ppufile.getbyte;
+         tobjectsymtable(symtable).fieldalignment:=ppufile.getbyte;
+         tobjectsymtable(symtable).recordalignment:=ppufile.getbyte;
          tobjectsymtable(symtable).ppuload(ppufile);
 
          symtable.defowner:=self;
@@ -4832,7 +4807,8 @@ implementation
            end;
 
          ppufile.putlongint(tobjectsymtable(symtable).datasize);
-         ppufile.putbyte(tobjectsymtable(symtable).dataalignment);
+         ppufile.putbyte(tobjectsymtable(symtable).fieldalignment);
+         ppufile.putbyte(tobjectsymtable(symtable).recordalignment);
          ppufile.writeentry(ibobjectdef);
 
          tobjectsymtable(symtable).ppuwrite(ppufile);
@@ -4938,7 +4914,7 @@ implementation
         else
           begin
              tobjectsymtable(symtable).datasize:=align(tobjectsymtable(symtable).datasize,
-                 tobjectsymtable(symtable).dataalignment);
+                 tobjectsymtable(symtable).fieldalignment);
              vmt_offset:=tobjectsymtable(symtable).datasize;
              inc(tobjectsymtable(symtable).datasize,POINTER_SIZE);
              include(objectoptions,oo_has_vmt);
@@ -5045,7 +5021,7 @@ implementation
 
     function tobjectdef.alignment:longint;
       begin
-        alignment:=tobjectsymtable(symtable).dataalignment;
+        alignment:=tobjectsymtable(symtable).recordalignment;
       end;
 
 
@@ -6185,7 +6161,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.210  2004-01-27 10:29:32  daniel
+  Revision 1.211  2004-01-28 20:30:18  peter
+    * record alignment splitted in fieldalignment and recordalignment,
+      the latter is used when this record is inserted in another record.
+
+  Revision 1.210  2004/01/27 10:29:32  daniel
     * Fix string type stab generation. String constant still unsupported.
 
   Revision 1.209  2004/01/26 19:54:42  daniel

+ 40 - 31
compiler/symtable.pas

@@ -92,8 +92,9 @@ interface
 
        tabstractrecordsymtable = class(tstoredsymtable)
        public
-          datasize  : longint;
-          dataalignment : byte;
+          datasize       : longint;
+          recordalignment,       { alignment required when inserting this record }
+          fieldalignment : byte; { alignment used when fields are inserted }
           constructor create(const n:string);
           procedure ppuload(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -978,7 +979,7 @@ implementation
       begin
         inherited create(n);
         datasize:=0;
-        dataalignment:=1;
+        fieldalignment:=1;
       end;
 
 
@@ -1040,52 +1041,56 @@ implementation
 
     procedure tabstractrecordsymtable.insertfield(sym : tvarsym;addsym:boolean);
       var
-        l,varalign : longint;
+        l,
+        varalignrecord,
+        varalignfield,
+        varalign : longint;
         vardef : tdef;
       begin
         if addsym then
           insert(sym);
-        { Calculate field offset }
-        l:=tvarsym(sym).getvaluesize;
-        vardef:=tvarsym(sym).vartype.def;
         { this symbol can't be loaded to a register }
         exclude(tvarsym(sym).varoptions,vo_regable);
         exclude(tvarsym(sym).varoptions,vo_fpuregable);
-        { get the alignment size }
+        { Calculate field offset }
+        l:=tvarsym(sym).getvaluesize;
+        vardef:=tvarsym(sym).vartype.def;
+        varalign:=vardef.alignment;
+        { Calc the alignment size for C style records }
         if (aktalignment.recordalignmax=-1) then
          begin
-           varalign:=vardef.alignment;
            if (varalign>4) and
               ((varalign mod 4)<>0) and
               (vardef.deftype=arraydef) then
              Message1(sym_w_wrong_C_pack,vardef.typename);
            if varalign=0 then
              varalign:=l;
-           if (dataalignment<aktalignment.maxCrecordalign) then
+           if (fieldalignment<aktalignment.maxCrecordalign) then
             begin
-              if (varalign>16) and (dataalignment<32) then
-               dataalignment:=32
-              else if (varalign>12) and (dataalignment<16) then
-               dataalignment:=16
+              if (varalign>16) and (fieldalignment<32) then
+               fieldalignment:=32
+              else if (varalign>12) and (fieldalignment<16) then
+               fieldalignment:=16
               { 12 is needed for long double }
-              else if (varalign>8) and (dataalignment<12) then
-               dataalignment:=12
-              else if (varalign>4) and (dataalignment<8) then
-               dataalignment:=8
-              else if (varalign>2) and (dataalignment<4) then
-               dataalignment:=4
-              else if (varalign>1) and (dataalignment<2) then
-               dataalignment:=2;
+              else if (varalign>8) and (fieldalignment<12) then
+               fieldalignment:=12
+              else if (varalign>4) and (fieldalignment<8) then
+               fieldalignment:=8
+              else if (varalign>2) and (fieldalignment<4) then
+               fieldalignment:=4
+              else if (varalign>1) and (fieldalignment<2) then
+               fieldalignment:=2;
             end;
-           dataalignment:=min(dataalignment,aktalignment.maxCrecordalign);
-         end
-        else
-         varalign:=vardef.alignment;
+           fieldalignment:=min(fieldalignment,aktalignment.maxCrecordalign);
+         end;
         if varalign=0 then
           varalign:=size_2_align(l);
-        varalign:=used_align(varalign,aktalignment.recordalignmin,dataalignment);
-        tvarsym(sym).fieldoffset:=align(datasize,varalign);
+        varalignfield:=used_align(varalign,aktalignment.recordalignmin,fieldalignment);
+        tvarsym(sym).fieldoffset:=align(datasize,varalignfield);
         datasize:=tvarsym(sym).fieldoffset+l;
+        { Calc alignment needed for this record }
+        varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.recordalignmax);
+        recordalignment:=max(recordalignment,varalignrecord);
       end;
 
 
@@ -1112,7 +1117,7 @@ implementation
         storesize,storealign : longint;
       begin
         storesize:=tsymt.datasize;
-        storealign:=tsymt.dataalignment;
+        storealign:=tsymt.fieldalignment;
         tsymt.datasize:=offset;
         ps:=tvarsym(symindex.first);
         while assigned(ps) do
@@ -1143,7 +1148,7 @@ implementation
             pd:=npd;
           end;
         tsymt.datasize:=storesize;
-        tsymt.dataalignment:=storealign;
+        tsymt.fieldalignment:=storealign;
       end;
 
 
@@ -2297,7 +2302,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.126  2004-01-26 16:12:28  daniel
+  Revision 1.127  2004-01-28 20:30:18  peter
+    * record alignment splitted in fieldalignment and recordalignment,
+      the latter is used when this record is inserted in another record.
+
+  Revision 1.126  2004/01/26 16:12:28  daniel
     * reginfo now also only allocated during register allocation
     * third round of gdb cleanups: kick out most of concatstabto