diff options
author | Russ Cox <rsc@golang.org> | 2014-09-05 16:51:45 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-09-05 16:51:45 -0400 |
commit | a67917471ff28c5e4c37ba1eca98f0a6ded14c68 (patch) | |
tree | 9f648acbe29f95d7e5e147529054c3a0a850f4dd /src/pkg/runtime/panic1.go | |
parent | afde047b8fdb004d86026261af9e8f11c9180a8a (diff) | |
download | go-a67917471ff28c5e4c37ba1eca98f0a6ded14c68.tar.gz |
runtime: use reflect.call during panic instead of newstackcall
newstackcall creates a new stack segment, and we want to
be able to throw away all that code.
LGTM=khr
R=khr, iant
CC=dvyukov, golang-codereviews, r
https://codereview.appspot.com/139270043
Diffstat (limited to 'src/pkg/runtime/panic1.go')
-rw-r--r-- | src/pkg/runtime/panic1.go | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/pkg/runtime/panic1.go b/src/pkg/runtime/panic1.go index 6d939703d..7bdfb4b2c 100644 --- a/src/pkg/runtime/panic1.go +++ b/src/pkg/runtime/panic1.go @@ -56,10 +56,17 @@ func gopanic(e interface{}) { dabort.link = gp._defer gp._defer = (*_defer)(noescape(unsafe.Pointer(&dabort))) p._defer = d + p.outerwrap = gp.panicwrap - newstackcall(d.fn, unsafe.Pointer(&d.args), uint32(d.siz)) + // TODO(rsc): I am pretty sure the panicwrap manipulation here is not correct. + // It is close enough to pass all the tests we have, but I think it needs to be + // restored during recovery too. I will write better tests and fix it in a separate CL. - // Newstackcall did not panic. Remove dabort. + gp.panicwrap = 0 + reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz), (*_panic)(noescape(unsafe.Pointer(&p)))) + gp.panicwrap = p.outerwrap + + // reflectcall did not panic. Remove dabort. if gp._defer != &dabort { gothrow("bad defer entry in panic") } @@ -114,9 +121,11 @@ func gorecover(argp uintptr) interface{} { // while they are active on the stack. The linker emits adjustments of // g.panicwrap in the prologue and epilogue of functions marked as wrappers. gp := getg() - top := (*stktop)(unsafe.Pointer(gp.stackbase)) p := gp._panic - if p != nil && !p.recovered && top._panic && argp == gp.stackbase-uintptr(top.argsize+gp.panicwrap) { + // if p != nil { + // println("recover?", p, p.recovered, hex(argp), hex(p.argp), uintptr(gp.panicwrap), p != nil && !p.recovered && argp == p.argp-uintptr(gp.panicwrap)) + // } + if p != nil && !p.recovered && argp == p.argp-uintptr(gp.panicwrap) { p.recovered = true return p.arg } |