فهرست منبع

* 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