summaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/builtin.c5
-rw-r--r--src/cmd/gc/dcl.c14
-rw-r--r--src/cmd/gc/order.c6
-rw-r--r--src/cmd/gc/pgen.c2
-rw-r--r--src/cmd/gc/racewalk.c7
-rw-r--r--src/cmd/gc/reflect.c25
-rw-r--r--src/cmd/gc/runtime.go7
-rw-r--r--src/cmd/gc/sinit.c2
-rw-r--r--src/cmd/gc/walk.c32
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;