diff options
Diffstat (limited to 'src/cmd/gc')
-rw-r--r-- | src/cmd/gc/builtin.c | 5 | ||||
-rw-r--r-- | src/cmd/gc/dcl.c | 14 | ||||
-rw-r--r-- | src/cmd/gc/order.c | 6 | ||||
-rw-r--r-- | src/cmd/gc/pgen.c | 2 | ||||
-rw-r--r-- | src/cmd/gc/racewalk.c | 7 | ||||
-rw-r--r-- | src/cmd/gc/reflect.c | 25 | ||||
-rw-r--r-- | src/cmd/gc/runtime.go | 7 | ||||
-rw-r--r-- | src/cmd/gc/sinit.c | 2 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 32 |
9 files changed, 78 insertions, 22 deletions
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c index ee1ac1da4..5fbb4f0cf 100644 --- a/src/cmd/gc/builtin.c +++ b/src/cmd/gc/builtin.c @@ -84,9 +84,12 @@ char *runtimeimport = "func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 *any)\n" "func @\"\".closechan (@\"\".hchan·1 any)\n" "func @\"\".writebarrierptr (@\"\".dst·1 *any, @\"\".src·2 any)\n" - "func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n" "func @\"\".writebarrierstring (@\"\".dst·1 *any, @\"\".src·2 any)\n" "func @\"\".writebarrierslice (@\"\".dst·1 *any, @\"\".src·2 any)\n" + "func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n" + "func @\"\".writebarrierfat2 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n" + "func @\"\".writebarrierfat3 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n" + "func @\"\".writebarrierfat4 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n" "func @\"\".writebarrierfat (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n" "func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n" "func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n" diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 73c2581be..dfcf47520 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -488,6 +488,10 @@ colasdefn(NodeList *left, Node *defn) NodeList *l; Node *n; + for(l=left; l; l=l->next) + if(l->n->sym != S) + l->n->sym->flags |= SymUniq; + nnew = 0; nerr = 0; for(l=left; l; l=l->next) { @@ -499,6 +503,13 @@ colasdefn(NodeList *left, Node *defn) nerr++; continue; } + if((n->sym->flags & SymUniq) == 0) { + yyerrorl(defn->lineno, "%S repeated on left side of :=", n->sym); + n->diag++; + nerr++; + continue; + } + n->sym->flags &= ~SymUniq; if(n->sym->block == block) continue; @@ -547,6 +558,9 @@ ifacedcl(Node *n) if(n->op != ODCLFIELD || n->right == N) fatal("ifacedcl"); + if(isblank(n->left)) + yyerror("methods must have a unique non-blank name"); + dclcontext = PPARAM; markdcl(); funcdepth++; diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c index 3027ed27d..76820fde7 100644 --- a/src/cmd/gc/order.c +++ b/src/cmd/gc/order.c @@ -438,6 +438,9 @@ ordercall(Node *n, Order *order) // cases they are also typically registerizable, so not much harm done. // And this only applies to the multiple-assignment form. // We could do a more precise analysis if needed, like in walk.c. +// +// Ordermapassign also inserts these temporaries if needed for +// calling writebarrierfat with a pointer to n->right. static void ordermapassign(Node *n, Order *order) { @@ -451,7 +454,8 @@ ordermapassign(Node *n, Order *order) case OAS: order->out = list(order->out, n); - if((n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > widthptr)) && !isaddrokay(n->right)) { + // We call writebarrierfat only for values > 4 pointers long. See walk.c. + if((n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > 4*widthptr)) && !isaddrokay(n->right)) { m = n->left; n->left = ordertemp(m->type, order, 0); a = nod(OAS, m, n->left); diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c index 50c03788e..39028e3f8 100644 --- a/src/cmd/gc/pgen.c +++ b/src/cmd/gc/pgen.c @@ -182,6 +182,8 @@ compile(Node *fn) yyerror("missing function body", fn); goto ret; } + if(debug['A']) + goto ret; emitptrargsmap(); goto ret; } diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c index cb98ca247..c9e27fe56 100644 --- a/src/cmd/gc/racewalk.c +++ b/src/cmd/gc/racewalk.c @@ -210,12 +210,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip) case OCALLFUNC: // Instrument dst argument of runtime.writebarrier* calls // as we do not instrument runtime code. - if(n->left->sym != S && n->left->sym->pkg == runtimepkg && - (strcmp(n->left->sym->name, "writebarrierptr") == 0 || - strcmp(n->left->sym->name, "writebarrierstring") == 0 || - strcmp(n->left->sym->name, "writebarrierslice") == 0 || - strcmp(n->left->sym->name, "writebarrieriface") == 0 || - strcmp(n->left->sym->name, "writebarrierfat") == 0)) { + if(n->left->sym != S && n->left->sym->pkg == runtimepkg && strncmp(n->left->sym->name, "writebarrier", 12) == 0) { // Find the dst argument. // The list can be reordered, so it's not necessary just the first or the second element. for(l = n->list; l; l = l->next) { diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c index e229b3075..0f8802abc 100644 --- a/src/cmd/gc/reflect.c +++ b/src/cmd/gc/reflect.c @@ -716,9 +716,10 @@ static int dcommontype(Sym *s, int ot, Type *t) { int i, alg, sizeofAlg, gcprog; - Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1; + Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1, *sbits; uint8 gcmask[16]; static Sym *algarray; + uint64 x1, x2; char *p; if(ot != 0) @@ -804,8 +805,26 @@ dcommontype(Sym *s, int ot, Type *t) ot = dsymptr(s, ot, gcprog1, 0); } else { gengcmask(t, gcmask); - for(i = 0; i < 2*widthptr; i++) - ot = duint8(s, ot, gcmask[i]); + x1 = 0; + for(i=0; i<8; i++) + x1 = x1<<8 | gcmask[i]; + if(widthptr == 4) { + p = smprint("gcbits.%#016llux", x1); + } else { + x2 = 0; + for(i=0; i<8; i++) + x2 = x2<<8 | gcmask[i+8]; + p = smprint("gcbits.%#016llux%016llux", x1, x2); + } + sbits = pkglookup(p, runtimepkg); + if((sbits->flags & SymUniq) == 0) { + sbits->flags |= SymUniq; + for(i = 0; i < 2*widthptr; i++) + duint8(sbits, i, gcmask[i]); + ggloblsym(sbits, 2*widthptr, DUPOK|RODATA); + } + ot = dsymptr(s, ot, sbits, 0); + ot = duintptr(s, ot, 0); } p = smprint("%-uT", t); //print("dcommontype: %s\n", p); diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index fa927a58a..86afe67f1 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -112,6 +112,13 @@ func writebarrierptr(dst *any, src any) func writebarrierstring(dst *any, src any) func writebarrierslice(dst *any, src any) func writebarrieriface(dst *any, src any) + +// The unused *byte argument makes sure that src is 2-pointer-aligned, +// which is the maximum alignment on NaCl amd64p32 +// (and possibly on 32-bit systems if we start 64-bit aligning uint64s). +func writebarrierfat2(dst *any, _ *byte, src any) +func writebarrierfat3(dst *any, _ *byte, src any) +func writebarrierfat4(dst *any, _ *byte, src any) func writebarrierfat(typ *byte, dst *any, src *any) func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index 508747e5a..f050026d9 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -207,7 +207,7 @@ init2(Node *n, NodeList **out) if(n->op == OCLOSURE) init2list(n->closure->nbody, out); - if(n->op == ODOTMETH) + if(n->op == ODOTMETH || n->op == OCALLPART) init2(n->type->nname, out); } diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 713348c0c..241d7d74a 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -2040,30 +2040,42 @@ static Node* applywritebarrier(Node *n, NodeList **init) { Node *l, *r; + Type *t; if(n->left && n->right && needwritebarrier(n->left, n->right)) { + t = n->left->type; l = nod(OADDR, n->left, N); l->etype = 1; // addr does not escape - if(n->left->type->width == widthptr) { - n = mkcall1(writebarrierfn("writebarrierptr", n->left->type, n->right->type), T, init, + if(t->width == widthptr) { + n = mkcall1(writebarrierfn("writebarrierptr", t, n->right->type), T, init, l, n->right); - } else if(n->left->type->etype == TSTRING) { - n = mkcall1(writebarrierfn("writebarrierstring", n->left->type, n->right->type), T, init, + } else if(t->etype == TSTRING) { + n = mkcall1(writebarrierfn("writebarrierstring", t, n->right->type), T, init, l, n->right); - } else if(isslice(n->left->type)) { - n = mkcall1(writebarrierfn("writebarrierslice", n->left->type, n->right->type), T, init, + } else if(isslice(t)) { + n = mkcall1(writebarrierfn("writebarrierslice", t, n->right->type), T, init, l, n->right); - } else if(isinter(n->left->type)) { - n = mkcall1(writebarrierfn("writebarrieriface", n->left->type, n->right->type), T, init, + } else if(isinter(t)) { + n = mkcall1(writebarrierfn("writebarrieriface", t, n->right->type), T, init, l, n->right); + } else if(t->width == 2*widthptr) { + n = mkcall1(writebarrierfn("writebarrierfat2", t, n->right->type), T, init, + l, nodnil(), n->right); + } else if(t->width == 3*widthptr) { + n = mkcall1(writebarrierfn("writebarrierfat3", t, n->right->type), T, init, + l, nodnil(), n->right); + } else if(t->width == 4*widthptr) { + n = mkcall1(writebarrierfn("writebarrierfat4", t, n->right->type), T, init, + l, nodnil(), n->right); } else { r = n->right; while(r->op == OCONVNOP) r = r->left; r = nod(OADDR, r, N); r->etype = 1; // addr does not escape - n = mkcall1(writebarrierfn("writebarrierfat", n->left->type, r->left->type), T, init, - typename(n->left->type), l, r); + //warnl(n->lineno, "writebarrierfat %T %N", t, r); + n = mkcall1(writebarrierfn("writebarrierfat", t, r->left->type), T, init, + typename(t), l, r); } } return n; |