]> Cypherpunks repositories - gostls13.git/commitdiff
6g: fix out of registers bug
authorRuss Cox <rsc@golang.org>
Sat, 11 Feb 2012 03:19:34 +0000 (22:19 -0500)
committerRuss Cox <rsc@golang.org>
Sat, 11 Feb 2012 03:19:34 +0000 (22:19 -0500)
Fix it twice: reuse registers more aggressively in cgen abop,
and also release R14 and R15, which are no longer m and g.

Fixes #2669.

R=ken2
CC=golang-dev
https://golang.org/cl/5655056

src/cmd/6g/cgen.c
src/cmd/6g/gsubr.c
test/fixedbugs/bug410.go [new file with mode: 0644]

index fd8493231402be1d849e12a0c1eece87acbe306d..2521b02d23766dfc598ad9138c0a4b74fefa985c 100644 (file)
@@ -387,9 +387,9 @@ abop:       // asymmetric binary
                regalloc(&n2, nr->type, N);
                cgen(nr, &n2);
        } else {
-               regalloc(&n2, nr->type, N);
+               regalloc(&n2, nr->type, res);
                cgen(nr, &n2);
-               regalloc(&n1, nl->type, res);
+               regalloc(&n1, nl->type, N);
                cgen(nl, &n1);
        }
        gins(a, &n2, &n1);
index cf00c3c49406882baff0dcfa481925487aafc60a..22fea9b16604bb6b533a20f89744016e02db6522 100644 (file)
@@ -287,8 +287,6 @@ static      int     resvd[] =
        D_CX,   // for shift
        D_DX,   // for divide
        D_SP,   // for stack
-       D_R14,  // reserved for m
-       D_R15,  // reserved for u
 };
 
 void
@@ -340,6 +338,8 @@ anyregalloc(void)
        return 0;
 }
 
+static uintptr regpc[D_R15+1 - D_AX];
+
 /*
  * allocate register of type t, leave in n.
  * if o != N, o is desired fixed register.
@@ -372,11 +372,15 @@ regalloc(Node *n, Type *t, Node *o)
                                goto out;
                }
                for(i=D_AX; i<=D_R15; i++)
-                       if(reg[i] == 0)
+                       if(reg[i] == 0) {
+                               regpc[i-D_AX] = (uintptr)getcallerpc(&n);
                                goto out;
+                       }
 
-               yyerror("out of fixed registers");
-               goto err;
+               flusherrors();
+               for(i=0; i+D_AX<=D_R15; i++)
+                       print("%d %p\n", i, regpc[i]);
+               fatal("out of fixed registers");
 
        case TFLOAT32:
        case TFLOAT64:
@@ -388,18 +392,14 @@ regalloc(Node *n, Type *t, Node *o)
                for(i=D_X0; i<=D_X7; i++)
                        if(reg[i] == 0)
                                goto out;
-               yyerror("out of floating registers");
-               goto err;
+               fatal("out of floating registers");
 
        case TCOMPLEX64:
        case TCOMPLEX128:
                tempname(n, t);
                return;
        }
-       yyerror("regalloc: unknown type %T", t);
-
-err:
-       nodreg(n, t, 0);
+       fatal("regalloc: unknown type %T", t);
        return;
 
 out:
@@ -424,6 +424,8 @@ regfree(Node *n)
        if(reg[i] <= 0)
                fatal("regfree: reg not allocated");
        reg[i]--;
+       if(reg[i] == 0 && D_AX <= i && i <= D_R15)
+               regpc[i - D_AX] = 0;
 }
 
 /*
diff --git a/test/fixedbugs/bug410.go b/test/fixedbugs/bug410.go
new file mode 100644 (file)
index 0000000..6eee6cf
--- /dev/null
@@ -0,0 +1,24 @@
+// $G $D/$F.go
+
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Used to run 6g out of registers.  Issue 2669.
+
+package p
+
+type y struct {
+       num int
+}
+
+func zzz () {
+    k := make([]byte, 10)
+       arr := make ([]*y, 0)
+    for s := range arr {
+        x := make([]byte, 10)
+        for i := 0; i < 100 ; i++ {
+            x[i] ^= k[i-arr[s].num%0]
+        }
+    }
+}