shithub: mc

Download patch

ref: 7a7372b7f42a9c3c526868ee9c41323aa6b665e7
parent: d77ea4e5a34e9a7a54ed1302dcd0d0c9ef13fda9
author: Ori Bernstein <[email protected]>
date: Thu Oct 24 08:03:46 EDT 2013

Fix struct alignment.

    We over padded. This was bad for 2 reasons:
        - We wasted memory.
            For structs containing just bytes, we
            almost doubled the memory usage.

        - We were not C compatible.
            Normally I wouldn't care, but for the syscall
            ABIs, our data needs to work.

--- a/6/simp.c
+++ b/6/simp.c
@@ -61,6 +61,11 @@
 static Type *tyword;
 static Type *tyvoid;
 
+static size_t tyalign(size_t sz, size_t eltsz)
+{
+    return align(sz, min(eltsz, Ptrsz));
+}
+
 static Type *base(Type *t)
 {
     assert(t->nsub == 1);
@@ -300,13 +305,22 @@
             assert(exprop(t->asize) == Olit);
             return t->asize->expr.args[0]->lit.intval * tysize(t->sub[0]);
         case Tytuple:
-            for (i = 0; i < t->nsub; i++)
+            for (i = 0; i < t->nsub; i++) {
+                sz = tyalign(sz, tysize(t->sub[i]));
                 sz += tysize(t->sub[i]);
+            }
+            for (i = 0; i < t->nsub; i++)
+                sz = tyalign(sz, tysize(t->sub[i]));
             return sz;
             break;
         case Tystruct:
+            for (i = 0; i < t->nmemb; i++) {
+                sz = tyalign(sz, size(t->sdecls[i]));
+                sz += size(t->sdecls[i]);
+            }
+            /* the whole struct size should match the biggest alignment */
             for (i = 0; i < t->nmemb; i++)
-                sz += align(size(t->sdecls[i]), Ptrsz);
+                sz = tyalign(sz, size(t->sdecls[i]));
             return sz;
             break;
         case Tyunion:
@@ -522,6 +536,7 @@
             patarg = pat->expr.args;
             off = 0;
             for (i = 0; i < pat->expr.nargs; i++) {
+                off = tyalign(off, size(patarg[i]));
                 next = genlbl();
                 v = load(addk(addr(s, val, exprtype(patarg[i])), off));
                 umatch(s, patarg[i], v, exprtype(patarg[i]), next, iffalse);
@@ -631,6 +646,7 @@
     nl = ty->sdecls;
     off = 0;
     for (i = 0; i < ty->nmemb; i++) {
+        off = tyalign(off, size(nl[i]));
         if (!strcmp(namestr(memb), declname(nl[i])))
             return off;
         off += size(nl[i]);
@@ -930,6 +946,7 @@
     off = 0;
     for (i = 0; i < lhs->expr.nargs; i++) {
         lv = lval(s, args[i]);
+        off = tyalign(off, size(lv));
         prv = add(addr(s, rhs, exprtype(args[i])), disp(rhs->line, off));
         if (stacknode(args[i])) {
             sz = disp(lhs->line, size(lv));
@@ -1008,6 +1025,7 @@
 
     off = 0;
     for (i = 0; i < n->expr.nargs; i++) {
+        off = tyalign(off, size(args[i]));
         assignat(s, r, off, args[i]);
         off += size(args[i]);
     }