]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: let stack copier update Panic structs for us
authorRuss Cox <rsc@golang.org>
Tue, 9 Sep 2014 01:02:36 +0000 (21:02 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 9 Sep 2014 01:02:36 +0000 (21:02 -0400)
It already is updating parts of them; we're just getting lucky
retraversing them and not finding much to do.
Change argp to a pointer so that it will be updated too.
Existing tests break if you apply the change to adjustpanics
without also updating the type of argp.

LGTM=khr
R=khr
CC=golang-codereviews
https://golang.org/cl/139380043

src/runtime/panic.go
src/runtime/runtime.h
src/runtime/stack.c

index a5a8fbd6dd185a5dad5be87b1843bbb522a45ae9..52ab654646f0108c9853200e3ef73fb8fe55ef14 100644 (file)
@@ -287,9 +287,9 @@ func gopanic(e interface{}) {
                gp._defer = (*_defer)(noescape(unsafe.Pointer(&dabort)))
                p._defer = d
 
-               p.argp = getargp(0)
+               p.argp = unsafe.Pointer(getargp(0))
                reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
-               p.argp = 0
+               p.argp = nil
 
                // reflectcall did not panic. Remove dabort.
                if gp._defer != &dabort {
@@ -362,7 +362,7 @@ func gorecover(argp uintptr) interface{} {
        // If they match, the caller is the one who can recover.
        gp := getg()
        p := gp._panic
-       if p != nil && !p.recovered && argp == p.argp {
+       if p != nil && !p.recovered && argp == uintptr(p.argp) {
                p.recovered = true
                return p.arg
        }
index e6db8cb83613a4d9ce186ffb78da2fc3edf3f136..9584c5dfcc0dd2d112f4fe47465272d6adbe651e 100644 (file)
@@ -653,7 +653,7 @@ struct Defer
  */
 struct Panic
 {
-       uintptr argp;   // pointer to arguments of deferred call run during panic; cannot move - known to liblink
+       void*   argp;   // pointer to arguments of deferred call run during panic; cannot move - known to liblink
        Eface   arg;            // argument to panic
        Panic*  link;           // link to earlier panic
        Defer*  defer;          // current executing defer
index ca0eed06f983b773942613579b30b2136230369c..8461c01f370abc48c71eb46e7efe45eff06ffd31 100644 (file)
@@ -712,6 +712,10 @@ adjustdefers(G *gp, AdjustInfo *adjinfo)
                        // get adjusted appropriately.
                        // This only happens for runtime.main and runtime.gopanic now,
                        // but a compiler optimization could do more of this.
+                       // If such an optimization were introduced, Defer.argp should
+                       // change to have pointer type so that it will be updated by
+                       // the stack copying. Today both of those on-stack defers
+                       // set argp = NoArgs, so no adjustment is necessary.
                        *dp = (Defer*)((byte*)d + adjinfo->delta);
                        continue;
                }
@@ -751,17 +755,11 @@ adjustdefers(G *gp, AdjustInfo *adjinfo)
 static void
 adjustpanics(G *gp, AdjustInfo *adjinfo)
 {
-       Panic *p, **l;
-
-       // only the topmost panic is on the current stack
-       for(l = &gp->panic; (p = *l) != nil; ) {
-               if(adjinfo->oldstk <= (byte*)p && (byte*)p < adjinfo->oldbase)
-                       *l = (Panic*)((byte*)p + adjinfo->delta);
-               l = &p->link;
-               
-               if(adjinfo->oldstk <= (byte*)p->argp && (byte*)p->argp < adjinfo->oldbase)
-                       p->argp += adjinfo->delta;
-       }
+       // Panic structs are all on the stack
+       // and are adjusted by stack copying.
+       // The only pointer we need to update is gp->panic, the head of the list.
+       if(adjinfo->oldstk <= (byte*)gp->panic && (byte*)gp->panic < adjinfo->oldbase)
+               gp->panic = (Panic*)((byte*)gp->panic + adjinfo->delta);
 }
 
 static void