]> Cypherpunks repositories - gostls13.git/commitdiff
gc: align structs according to max alignment of fields
authorRuss Cox <rsc@golang.org>
Mon, 13 Dec 2010 21:22:19 +0000 (16:22 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 13 Dec 2010 21:22:19 +0000 (16:22 -0500)
cc: same
runtime: test cc alignment (required moving #define of offsetof to runtime.h)
fix bug260

Fixes #482.
Fixes #609.

R=ken2, r
CC=golang-dev
https://golang.org/cl/3563042

22 files changed:
src/cmd/5c/swt.c
src/cmd/5c/txt.c
src/cmd/6c/cgen.c
src/cmd/6c/swt.c
src/cmd/6c/txt.c
src/cmd/8c/cgen64.c
src/cmd/8c/swt.c
src/cmd/8c/txt.c
src/cmd/cc/cc.h
src/cmd/cc/dcl.c
src/cmd/cc/pgen.c
src/cmd/cc/pswt.c
src/cmd/gc/align.c
src/cmd/gc/typecheck.c
src/pkg/reflect/value.go
src/pkg/runtime/debug.go
src/pkg/runtime/hashmap.h
src/pkg/runtime/malloc.goc
src/pkg/runtime/runtime.c
src/pkg/runtime/runtime.h
test/fixedbugs/bug260.go [moved from test/bugs/bug260.go with 88% similarity]
test/golden.out

index 7740ad2e5feee3bb47654750951348c029b3e94e..43eb73c943ae814ddd6e10b8a7eebe5f787ff643 100644 (file)
@@ -606,7 +606,7 @@ zaddr(char *bp, Adr *a, int s)
 }
 
 int32
-align(int32 i, Type *t, int op)
+align(int32 i, Type *t, int op, int32 *maxalign)
 {
        int32 o;
        Type *v;
@@ -620,7 +620,9 @@ align(int32 i, Type *t, int op)
                break;
 
        case Asu2:      /* padding at end of a struct */
-               w = SZ_LONG;
+               w = *maxalign;
+               if(w < 1)
+                       w = 1;
                if(packflg)
                        w = packflg;
                break;
@@ -628,10 +630,16 @@ align(int32 i, Type *t, int op)
        case Ael1:      /* initial align of struct element */
                for(v=t; v->etype==TARRAY; v=v->link)
                        ;
-               w = ewidth[v->etype];
-               if(w <= 0 || w >= SZ_LONG)
-                       w = SZ_LONG;
-               if(packflg)
+               if(v->etype == TSTRUCT || v->etype == TUNION)
+                       w = v->align;
+               else {
+                       w = ewidth[v->etype];
+                       if(w == 8)
+                               w = 4;
+               }
+               if(w < 1 || w > SZ_LONG)
+                       fatal(Z, "align");
+               if(packflg) 
                        w = packflg;
                break;
 
@@ -641,8 +649,8 @@ align(int32 i, Type *t, int op)
 
        case Aarg0:     /* initial passbyptr argument in arg list */
                if(typesuv[t->etype]) {
-                       o = align(o, types[TIND], Aarg1);
-                       o = align(o, types[TIND], Aarg2);
+                       o = align(o, types[TIND], Aarg1, nil);
+                       o = align(o, types[TIND], Aarg2, nil);
                }
                break;
 
@@ -661,12 +669,14 @@ align(int32 i, Type *t, int op)
                break;
 
        case Aaut3:     /* total align of automatic */
-               o = align(o, t, Ael2);
-               o = align(o, t, Ael1);
+               o = align(o, t, Ael2, nil);
+               o = align(o, t, Ael1, nil);
                w = SZ_LONG;    /* because of a pun in cc/dcl.c:contig() */
                break;
        }
        o = xround(o, w);
+       if(maxalign != nil && *maxalign < w)
+               *maxalign = w;
        if(debug['A'])
                print("align %s %d %T = %d\n", bnames[op], i, t, o);
        return o;
index 1ba8ae2c4e1ae4b3c04cf33866e745546e54ac02..0f17cea89b3aaf1834c55c7e0cb322e5e36e6752 100644 (file)
@@ -388,7 +388,7 @@ err:
 void
 regsalloc(Node *n, Node *nn)
 {
-       cursafe = align(cursafe, nn->type, Aaut3);
+       cursafe = align(cursafe, nn->type, Aaut3, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
        *n = *nodsafe;
        n->xoffset = -(stkoff + cursafe);
@@ -402,22 +402,22 @@ regaalloc1(Node *n, Node *nn)
 {
        nodreg(n, nn, REGARG);
        reg[REGARG]++;
-       curarg = align(curarg, nn->type, Aarg1);
-       curarg = align(curarg, nn->type, Aarg2);
+       curarg = align(curarg, nn->type, Aarg1, nil);
+       curarg = align(curarg, nn->type, Aarg2, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
 }
 
 void
 regaalloc(Node *n, Node *nn)
 {
-       curarg = align(curarg, nn->type, Aarg1);
+       curarg = align(curarg, nn->type, Aarg1, nil);
        *n = *nn;
        n->op = OINDREG;
        n->reg = REGSP;
        n->xoffset = curarg + SZ_LONG;
        n->complex = 0;
        n->addable = 20;
-       curarg = align(curarg, nn->type, Aarg2);
+       curarg = align(curarg, nn->type, Aarg2, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
 }
 
index dd8573c07522796f253aa3eceab6f95cd241f04a..90394884f6c3827946aa7f7e8a9aaa38e88c1bd3 100644 (file)
@@ -1928,7 +1928,7 @@ vaddr(Node *n, int a)
 int32
 hi64v(Node *n)
 {
-       if(align(0, types[TCHAR], Aarg1))       /* isbigendian */
+       if(align(0, types[TCHAR], Aarg1, nil))  /* isbigendian */
                return (int32)(n->vconst) & ~0L;
        else
                return (int32)((uvlong)n->vconst>>32) & ~0L;
@@ -1937,7 +1937,7 @@ hi64v(Node *n)
 int32
 lo64v(Node *n)
 {
-       if(align(0, types[TCHAR], Aarg1))       /* isbigendian */
+       if(align(0, types[TCHAR], Aarg1, nil))  /* isbigendian */
                return (int32)((uvlong)n->vconst>>32) & ~0L;
        else
                return (int32)(n->vconst) & ~0L;
index 1597fdf34eba99bf70b860690b1cd6b4bc8600c4..47975a0c8e7a36c64cd1539aa8ca0d4513a12245 100644 (file)
@@ -503,7 +503,7 @@ zaddr(Biobuf *b, Adr *a, int s)
 }
 
 int32
-align(int32 i, Type *t, int op)
+align(int32 i, Type *t, int op, int32 *maxalign)
 {
        int32 o;
        Type *v;
@@ -517,7 +517,9 @@ align(int32 i, Type *t, int op)
                break;
 
        case Asu2:      /* padding at end of a struct */
-               w = SZ_VLONG;
+               w = *maxalign;
+               if(w < 1)
+                       w = 1;
                if(packflg)
                        w = packflg;
                break;
@@ -525,10 +527,13 @@ align(int32 i, Type *t, int op)
        case Ael1:      /* initial align of struct element */
                for(v=t; v->etype==TARRAY; v=v->link)
                        ;
-               w = ewidth[v->etype];
-               if(w <= 0 || w >= SZ_VLONG)
-                       w = SZ_VLONG;
-               if(packflg)
+               if(v->etype == TSTRUCT || v->etype == TUNION)
+                       w = v->align;
+               else
+                       w = ewidth[v->etype];
+               if(w < 1 || w > SZ_VLONG)
+                       fatal(Z, "align");
+               if(packflg) 
                        w = packflg;
                break;
 
@@ -538,8 +543,8 @@ align(int32 i, Type *t, int op)
 
        case Aarg0:     /* initial passbyptr argument in arg list */
                if(typesu[t->etype]) {
-                       o = align(o, types[TIND], Aarg1);
-                       o = align(o, types[TIND], Aarg2);
+                       o = align(o, types[TIND], Aarg1, nil);
+                       o = align(o, types[TIND], Aarg2, nil);
                }
                break;
 
@@ -560,11 +565,13 @@ align(int32 i, Type *t, int op)
                break;
 
        case Aaut3:     /* total align of automatic */
-               o = align(o, t, Ael1);
-               o = align(o, t, Ael2);
+               o = align(o, t, Ael1, nil);
+               o = align(o, t, Ael2, nil);
                break;
        }
        o = xround(o, w);
+       if(maxalign && *maxalign < w)
+               *maxalign = w;
        if(debug['A'])
                print("align %s %d %T = %d\n", bnames[op], i, t, o);
        return o;
index 29b2e1312dd306e80567b5f520b5344dcf478bc5..a78ba227bcb585c914ac9c945477d01d47eb9fbc 100644 (file)
@@ -424,7 +424,7 @@ err:
 void
 regsalloc(Node *n, Node *nn)
 {
-       cursafe = align(cursafe, nn->type, Aaut3);
+       cursafe = align(cursafe, nn->type, Aaut3, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
        *n = *nodsafe;
        n->xoffset = -(stkoff + cursafe);
@@ -440,22 +440,22 @@ regaalloc1(Node *n, Node *nn)
                diag(n, "regaalloc1 and REGARG<0");
        nodreg(n, nn, REGARG);
        reg[REGARG]++;
-       curarg = align(curarg, nn->type, Aarg1);
-       curarg = align(curarg, nn->type, Aarg2);
+       curarg = align(curarg, nn->type, Aarg1, nil);
+       curarg = align(curarg, nn->type, Aarg2, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
 }
 
 void
 regaalloc(Node *n, Node *nn)
 {
-       curarg = align(curarg, nn->type, Aarg1);
+       curarg = align(curarg, nn->type, Aarg1, nil);
        *n = *nn;
        n->op = OINDREG;
        n->reg = REGSP;
        n->xoffset = curarg;
        n->complex = 0;
        n->addable = 20;
-       curarg = align(curarg, nn->type, Aarg2);
+       curarg = align(curarg, nn->type, Aarg2, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
 }
 
index ce1512c51a09b9745be24694edccd66a8375a354..3424f762c53a817e964e3a3db073bc5088d858b9 100644 (file)
@@ -57,7 +57,7 @@ vaddr(Node *n, int a)
 int32
 hi64v(Node *n)
 {
-       if(align(0, types[TCHAR], Aarg1))       /* isbigendian */
+       if(align(0, types[TCHAR], Aarg1, nil))  /* isbigendian */
                return (int32)(n->vconst) & ~0L;
        else
                return (int32)((uvlong)n->vconst>>32) & ~0L;
@@ -66,7 +66,7 @@ hi64v(Node *n)
 int32
 lo64v(Node *n)
 {
-       if(align(0, types[TCHAR], Aarg1))       /* isbigendian */
+       if(align(0, types[TCHAR], Aarg1, nil))  /* isbigendian */
                return (int32)((uvlong)n->vconst>>32) & ~0L;
        else
                return (int32)(n->vconst) & ~0L;
index 46a0290d9d8075d73fa5c5c5ed033b35e9be7a03..be48885f8155f12a69bd829d87108438022f6619 100644 (file)
@@ -501,7 +501,7 @@ zaddr(Biobuf *b, Adr *a, int s)
 }
 
 int32
-align(int32 i, Type *t, int op)
+align(int32 i, Type *t, int op, int32 *maxalign)
 {
        int32 o;
        Type *v;
@@ -515,7 +515,9 @@ align(int32 i, Type *t, int op)
                break;
 
        case Asu2:      /* padding at end of a struct */
-               w = SZ_LONG;
+               w = *maxalign;
+               if(w < 1)
+                       w = 1;
                if(packflg)
                        w = packflg;
                break;
@@ -523,10 +525,16 @@ align(int32 i, Type *t, int op)
        case Ael1:      /* initial align of struct element */
                for(v=t; v->etype==TARRAY; v=v->link)
                        ;
-               w = ewidth[v->etype];
-               if(w <= 0 || w >= SZ_LONG)
-                       w = SZ_LONG;
-               if(packflg)
+               if(v->etype == TSTRUCT || v->etype == TUNION)
+                       w = v->align;
+               else {
+                       w = ewidth[v->etype];
+                       if(w == 8)
+                               w = 4;
+               }
+               if(w < 1 || w > SZ_LONG)
+                       fatal(Z, "align");
+               if(packflg) 
                        w = packflg;
                break;
 
@@ -536,8 +544,8 @@ align(int32 i, Type *t, int op)
 
        case Aarg0:     /* initial passbyptr argument in arg list */
                if(typesuv[t->etype]) {
-                       o = align(o, types[TIND], Aarg1);
-                       o = align(o, types[TIND], Aarg2);
+                       o = align(o, types[TIND], Aarg1, nil);
+                       o = align(o, types[TIND], Aarg2, nil);
                }
                break;
 
@@ -558,11 +566,13 @@ align(int32 i, Type *t, int op)
                break;
 
        case Aaut3:     /* total align of automatic */
-               o = align(o, t, Ael1);
-               o = align(o, t, Ael2);
+               o = align(o, t, Ael1, nil);
+               o = align(o, t, Ael2, nil);
                break;
        }
        o = xround(o, w);
+       if(maxalign && *maxalign < w)
+               *maxalign = w;
        if(debug['A'])
                print("align %s %d %T = %d\n", bnames[op], i, t, o);
        return o;
index 4cfd7bc1e6fbfb5f798010fc41484442c3488ef5..0dd387d11aef357558d31fee629451648bc63da7 100644 (file)
@@ -385,7 +385,7 @@ err:
 void
 regsalloc(Node *n, Node *nn)
 {
-       cursafe = align(cursafe, nn->type, Aaut3);
+       cursafe = align(cursafe, nn->type, Aaut3, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
        *n = *nodsafe;
        n->xoffset = -(stkoff + cursafe);
@@ -399,22 +399,22 @@ regaalloc1(Node *n, Node *nn)
 {
        nodreg(n, nn, REGARG);
        reg[REGARG]++;
-       curarg = align(curarg, nn->type, Aarg1);
-       curarg = align(curarg, nn->type, Aarg2);
+       curarg = align(curarg, nn->type, Aarg1, nil);
+       curarg = align(curarg, nn->type, Aarg2, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
 }
 
 void
 regaalloc(Node *n, Node *nn)
 {
-       curarg = align(curarg, nn->type, Aarg1);
+       curarg = align(curarg, nn->type, Aarg1, nil);
        *n = *nn;
        n->op = OINDREG;
        n->reg = REGSP;
        n->xoffset = curarg;
        n->complex = 0;
        n->addable = 20;
-       curarg = align(curarg, nn->type, Aarg2);
+       curarg = align(curarg, nn->type, Aarg2, nil);
        maxargsafe = maxround(maxargsafe, cursafe+curarg);
 }
 
index 69adcccb00c7f2d1919ece702f0b70ad50a59820..3649bf5f6a168cbf406660a389cac8040e24b001 100644 (file)
@@ -166,6 +166,7 @@ struct      Type
        uchar   nbits;
        uchar   etype;
        uchar   garb;
+       uchar   align;
 };
 
 #define        T       ((Type*)0)
@@ -785,7 +786,7 @@ int32       outlstring(ushort*, int32);
 void   sextern(Sym*, Node*, int32, int32);
 void   xcom(Node*);
 int32  exreg(Type*);
-int32  align(int32, Type*, int);
+int32  align(int32, Type*, int, int32*);
 int32  maxround(int32, int32);
 
 extern schar   ewidth[];
index 3aaa2c155977a65f2dc5cf44f65cfdebbb764141..f629925d1c93e0471b17e52b79d19d66d0894d1d 100644 (file)
@@ -552,9 +552,10 @@ void
 sualign(Type *t)
 {
        Type *l;
-       int32 o, w;
+       int32 o, w, maxal;
 
        o = 0;
+       maxal = 0;
        switch(t->etype) {
 
        case TSTRUCT:
@@ -577,13 +578,14 @@ sualign(Type *t)
                                                        l->sym->name);
                                        else
                                                diag(Z, "incomplete structure element");
-                               w = align(w, l, Ael1);
+                               w = align(w, l, Ael1, &maxal);
                                l->offset = w;
-                               w = align(w, l, Ael2);
+                               w = align(w, l, Ael2, &maxal);
                        }
                }
-               w = align(w, t, Asu2);
+               w = align(w, t, Asu2, &maxal);
                t->width = w;
+               t->align = maxal;
                acidtype(t);
                pickletype(t);
                return;
@@ -600,12 +602,13 @@ sualign(Type *t)
                                        diag(Z, "incomplete union element");
                        l->offset = 0;
                        l->shift = 0;
-                       o = align(align(0, l, Ael1), l, Ael2);
+                       o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal);
                        if(o > w)
                                w = o;
                }
-               w = align(w, t, Asu2);
+               w = align(w, t, Asu2, &maxal);
                t->width = w;
+               t->align = maxal;
                acidtype(t);
                pickletype(t);
                return;
@@ -663,7 +666,7 @@ argmark(Node *n, int pass)
 {
        Type *t;
 
-       autoffset = align(0, thisfn->link, Aarg0);
+       autoffset = align(0, thisfn->link, Aarg0, nil);
        stkoff = 0;
        for(; n->left != Z; n = n->left) {
                if(n->op != OFUNC || n->left->op != ONAME)
@@ -745,9 +748,9 @@ loop:
                                firstarg = s;
                                firstargtype = s->type;
                        }
-                       autoffset = align(autoffset, s->type, Aarg1);
+                       autoffset = align(autoffset, s->type, Aarg1, nil);
                        s->offset = autoffset;
-                       autoffset = align(autoffset, s->type, Aarg2);
+                       autoffset = align(autoffset, s->type, Aarg2, nil);
                } else
                        dodecl(pdecl, CXXX, types[TINT], n);
                break;
@@ -1275,7 +1278,7 @@ adecl(int c, Type *t, Sym *s)
        }
        switch(c) {
        case CAUTO:
-               autoffset = align(autoffset, t, Aaut3);
+               autoffset = align(autoffset, t, Aaut3, nil);
                stkoff = maxround(stkoff, autoffset);
                s->offset = -autoffset;
                break;
@@ -1285,10 +1288,10 @@ adecl(int c, Type *t, Sym *s)
                        firstarg = s;
                        firstargtype = t;
                }
-               autoffset = align(autoffset, t, Aarg1);
+               autoffset = align(autoffset, t, Aarg1, nil);
                if(s)
                        s->offset = autoffset;
-               autoffset = align(autoffset, t, Aarg2);
+               autoffset = align(autoffset, t, Aarg2, nil);
                break;
        }
 }
@@ -1587,7 +1590,7 @@ contig(Sym *s, Node *n, int32 v)
                if(v != 0)
                        diag(n, "automatic adjustable array: %s", s->name);
                v = s->offset;
-               autoffset = align(autoffset, s->type, Aaut3);
+               autoffset = align(autoffset, s->type, Aaut3, nil);
                s->offset = -autoffset;
                stkoff = maxround(stkoff, autoffset);
                symadjust(s, n, v - s->offset);
index cd6fffc578754089b2bf6b90d58a6c017f25c5e1..a9d7f1ef4ccd3122c0bc8a1072577b7e79ea095d 100644 (file)
@@ -37,7 +37,7 @@ argsize(void)
        int32 s;
 
 //print("t=%T\n", thisfn);
-       s = align(0, thisfn->link, Aarg0);
+       s = align(0, thisfn->link, Aarg0, nil);
        for(t=thisfn->down; t!=T; t=t->down) {
                switch(t->etype) {
                case TVOID:
@@ -47,8 +47,8 @@ argsize(void)
                        s += 64;
                        break;
                default:
-                       s = align(s, t, Aarg1);
-                       s = align(s, t, Aarg2);
+                       s = align(s, t, Aarg1, nil);
+                       s = align(s, t, Aarg2, nil);
                        break;
                }
 //print("      %d %T\n", s, t);
@@ -99,7 +99,7 @@ codgen(Node *n, Node *nn)
                        nod1 = *nodret->left;
                        nod1.sym = firstarg;
                        nod1.type = firstargtype;
-                       nod1.xoffset = align(0, firstargtype, Aarg1);
+                       nod1.xoffset = align(0, firstargtype, Aarg1, nil);
                        nod1.etype = firstargtype->etype;
                        nodreg(&nod, &nod1, REGARG);
                        gmove(&nod, &nod1);
index 891836c54341bd635a57bf70873dc13caf606337..0e402dea71044f4ffc5cab272febf32405b11334 100644 (file)
@@ -115,7 +115,7 @@ outlstring(ushort *s, int32 n)
        r = nstring;
        while(n > 0) {
                c = *s++;
-               if(align(0, types[TCHAR], Aarg1)) {
+               if(align(0, types[TCHAR], Aarg1, nil)) {
                        buf[0] = c>>8;
                        buf[1] = c;
                } else {
index 4b6d92e786aeadb67feec230ca9527fa371cca82..a3785e8718fbe59a3b3e0a5284576169463be337 100644 (file)
@@ -49,8 +49,8 @@ widstruct(Type *t, uint32 o, int flag)
                if(f->etype != TFIELD)
                        fatal("widstruct: not TFIELD: %lT", f);
                dowidth(f->type);
-               if(f->align > maxalign)
-                       maxalign = f->align;
+               if(f->type->align > maxalign)
+                       maxalign = f->type->align;
                if(f->type->width < 0)
                        fatal("invalid width %lld", f->type->width);
                w = f->type->width;
@@ -248,9 +248,11 @@ dowidth(Type *t)
        case TSTRUCT:
                if(t->funarg)
                        fatal("dowidth fn struct %T", t);
-               w = widstruct(t, 0, widthptr);
+               w = widstruct(t, 0, 1);
                if(w == 0)
                        w = 1;
+               //if(t->align < widthptr)
+               //      warn("align %d: %T\n", t->align, t);
                break;
 
        case TFUNC:
@@ -272,6 +274,8 @@ dowidth(Type *t)
                w = widstruct(*getinarg(t1), w, widthptr);
                w = widstruct(*getoutarg(t1), w, widthptr);
                t1->argwid = w;
+               if(w%widthptr)
+                       warn("bad type %T %d\n", t1, w);
                t->align = 1;
                break;
        }
index 5450862213eeb1a0325d757d3fab1c1cc44ee56a..4dd0d706bd1da6e639de8d188788c2c63e9fd719 100644 (file)
@@ -1124,7 +1124,7 @@ reswitch:
        case OPRINT:
        case OPRINTN:
                ok |= Etop;
-               typechecklist(n->list, Erv);
+               typechecklist(n->list, Erv | Eindir);  // Eindir: address does not escape
                goto ret;
 
        case OPANIC:
index a80112d34242752aa3e8403a1631f34422faaaf6..8b2c1a9530c74a1fed7e7d9dfe27bcfd8938161c 100644 (file)
@@ -730,8 +730,6 @@ type tiny struct {
 // Call calls the function fv with input parameters in.
 // It returns the function's output parameters as Values.
 func (fv *FuncValue) Call(in []Value) []Value {
-       var structAlign = Typeof((*tiny)(nil)).(*PtrType).Elem().Size()
-
        t := fv.Type().(*FuncType)
        nin := len(in)
        if fv.first != nil && !fv.isInterface {
@@ -757,7 +755,7 @@ func (fv *FuncValue) Call(in []Value) []Value {
                size = (size + a - 1) &^ (a - 1)
                size += tv.Size()
        }
-       size = (size + structAlign - 1) &^ (structAlign - 1)
+       size = (size + ptrSize - 1) &^ (ptrSize - 1)
        for i := 0; i < nout; i++ {
                tv := t.Out(i)
                a := uintptr(tv.Align())
@@ -767,9 +765,9 @@ func (fv *FuncValue) Call(in []Value) []Value {
 
        // size must be > 0 in order for &args[0] to be valid.
        // the argument copying is going to round it up to
-       // a multiple of 8 anyway, so make it 8 to begin with.
-       if size < 8 {
-               size = 8
+       // a multiple of ptrSize anyway, so make it ptrSize to begin with.
+       if size < ptrSize {
+               size = ptrSize
        }
 
        // round to pointer size
@@ -811,7 +809,7 @@ func (fv *FuncValue) Call(in []Value) []Value {
                memmove(addr(ptr+off), v.getAddr(), n)
                off += n
        }
-       off = (off + structAlign - 1) &^ (structAlign - 1)
+       off = (off + ptrSize - 1) &^ (ptrSize - 1)
 
        // Call
        call(*(**byte)(fv.addr), (*byte)(addr(ptr)), uint32(size))
index 3cc5472f6b02345a96080700cefec16f942b4e47..3ce35cc5ba98ba536a46e81ec18b00872aae58c9 100644 (file)
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "unsafe"
+
 // Breakpoint() executes a breakpoint trap.
 func Breakpoint()
 
@@ -73,6 +75,15 @@ type MemStatsType struct {
        }
 }
 
+var sizeof_C_MStats int // filled in by malloc.goc
+
+func init() {
+       if sizeof_C_MStats != unsafe.Sizeof(MemStats) {
+               println(sizeof_C_MStats, unsafe.Sizeof(MemStats))
+               panic("MStats vs MemStatsType size mismatch")
+       }
+}
+
 // MemStats holds statistics about the memory system.
 // The statistics are only approximate, as they are not interlocked on update.
 var MemStats MemStatsType
index 40dac6e9bd60780c321be273dfb50f513a7a910a..0737535b551cfcf5a5ac6156a5b1f1cbd061d258 100644 (file)
@@ -64,7 +64,6 @@
  */
 
 #define        malloc          runtime·mal
-#define        offsetof(s,m)   (uint32)(&(((s*)0)->m))
 #define        memset(a,b,c)   runtime·memclr((byte*)(a), (uint32)(c))
 #define        memcpy(a,b,c)   runtime·mcpy((byte*)(a),(byte*)(b),(uint32)(c))
 #define        assert(a)       if(!(a)) runtime·throw("assert")
index 405b05ee9654b553d622af82398171fc20e56cbd..f5ca9f9183eb6cf4f89e68f71795f0ec6c88bf37 100644 (file)
@@ -244,6 +244,8 @@ runtime·allocmcache(void)
        return c;
 }
 
+int32 runtime·sizeof_C_MStats = sizeof(MStats);
+
 void
 runtime·mallocinit(void)
 {
index f2b6c587e92c278482d00035644bdd3018ba6b97..a2e31d806f3d1f4bafc01519219f16524ea7d534 100644 (file)
@@ -258,6 +258,13 @@ runtime·check(void)
        float64 j;
        void* k;
        uint16* l;
+       struct x1 {
+               byte x;
+       };
+       struct y1 {
+               struct x1 x1;
+               byte y;
+       };
 
        if(sizeof(a) != 1) runtime·throw("bad a");
        if(sizeof(b) != 1) runtime·throw("bad b");
@@ -271,7 +278,9 @@ runtime·check(void)
        if(sizeof(j) != 8) runtime·throw("bad j");
        if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k");
        if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l");
-//     prints(1"check ok\n");
+       if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1");
+       if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y");
+       if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1");
 
        uint32 z;
        z = 1;
index b0fa3891e6c651bd3ef362e1b9ce978da27bb2db..37c8103f341c41c767533a98e8ac2f8daa6557f4 100644 (file)
@@ -306,6 +306,7 @@ enum {
  */
 #define        nelem(x)        (sizeof(x)/sizeof((x)[0]))
 #define        nil             ((void*)0)
+#define        offsetof(s,m)   (uint32)(&(((s*)0)->m))
 
 /*
  * known to compiler
similarity index 88%
rename from test/bugs/bug260.go
rename to test/fixedbugs/bug260.go
index 6a6331e65b3d6c87a403cd3702f71709087fc81a..34757c70eefd70e46df756725c62edf4541a33ec 100644 (file)
@@ -10,9 +10,15 @@ import (
        "strconv"
 )
 
-type T1 struct { x uint8 }
-type T2 struct { x uint16 }
-type T4 struct { x uint32 }
+type T1 struct {
+       x uint8
+}
+type T2 struct {
+       x uint16
+}
+type T4 struct {
+       x uint32
+}
 
 func main() {
        report := len(os.Args) > 1
@@ -20,7 +26,7 @@ func main() {
        var b1 [10]T1
        a0, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[0])[2:], 16)
        a1, _ := strconv.Btoui64(fmt.Sprintf("%p", &b1[1])[2:], 16)
-       if a1 != a0 + 1 {
+       if a1 != a0+1 {
                fmt.Println("FAIL")
                if report {
                        fmt.Println("alignment should be 1, is", a1-a0)
@@ -30,7 +36,7 @@ func main() {
        var b2 [10]T2
        a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[0])[2:], 16)
        a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b2[1])[2:], 16)
-       if a1 != a0 + 2 {
+       if a1 != a0+2 {
                if status == 0 {
                        fmt.Println("FAIL")
                        status = 1
@@ -42,7 +48,7 @@ func main() {
        var b4 [10]T4
        a0, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[0])[2:], 16)
        a1, _ = strconv.Btoui64(fmt.Sprintf("%p", &b4[1])[2:], 16)
-       if a1 != a0 + 4 {
+       if a1 != a0+4 {
                if status == 0 {
                        fmt.Println("FAIL")
                        status = 1
index 49bca4b874b17eba73c447c88bc23ba74813597b..e587912a48df61fe167c1ed2d9ffd425916921b7 100644 (file)
@@ -173,7 +173,3 @@ panic: interface conversion: interface is main.T, not main.T
 panic PC=xxx
 
 == bugs/
-
-=========== bugs/bug260.go
-FAIL
-BUG: bug260 failed