diff options
author | Russ Cox <rsc@golang.org> | 2014-11-11 17:04:34 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-11-11 17:04:34 -0500 |
commit | bb9ee976541b2f008a1d1ded4bab7d823b313a53 (patch) | |
tree | a54192d2667891e2db5872bcbc150ea54db4e8ed /src/runtime/panic.go | |
parent | 6f55366e3789180fe24870e9ae8b064dae7d5f50 (diff) | |
download | go-bb9ee976541b2f008a1d1ded4bab7d823b313a53.tar.gz |
[dev.cc] runtime: convert panic and stack code from C to Go
The conversion was done with an automated tool and then
modified only as necessary to make it compile and run.
[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]
LGTM=r
R=r, dave
CC=austin, dvyukov, golang-codereviews, iant, khr
https://codereview.appspot.com/166520043
Diffstat (limited to 'src/runtime/panic.go')
-rw-r--r-- | src/runtime/panic.go | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/src/runtime/panic.go b/src/runtime/panic.go index 685ff5ca0..9f3b9a3aa 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -54,6 +54,11 @@ func throwinit() { // The compiler turns a defer statement into a call to this. //go:nosplit func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn + if getg().m.curg != getg() { + // go code on the m stack can't defer + gothrow("defer on m") + } + // the arguments of fn are in a perilous state. The stack map // for deferproc does not describe them. So we can't let garbage // collection or stack copying trigger until we've copied them out @@ -64,20 +69,18 @@ func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn if GOARCH == "arm" { argp += ptrSize // skip caller's saved link register } - mp := acquirem() - mp.scalararg[0] = uintptr(siz) - mp.ptrarg[0] = unsafe.Pointer(fn) - mp.scalararg[1] = argp - mp.scalararg[2] = getcallerpc(unsafe.Pointer(&siz)) - - if mp.curg != getg() { - // go code on the m stack can't defer - gothrow("defer on m") - } - - onM(deferproc_m) + callerpc := getcallerpc(unsafe.Pointer(&siz)) - releasem(mp) + onM(func() { + d := newdefer(siz) + if d._panic != nil { + gothrow("deferproc: d.panic != nil after newdefer") + } + d.fn = fn + d.pc = callerpc + d.argp = argp + memmove(add(unsafe.Pointer(d), unsafe.Sizeof(*d)), unsafe.Pointer(argp), uintptr(siz)) + }) // deferproc returns 0 normally. // a deferred func that stops a panic @@ -298,8 +301,6 @@ func Goexit() { goexit() } -func canpanic(*g) bool - // Print all currently active panics. Used when crashing. func printpanics(p *_panic) { if p.link != nil { @@ -318,6 +319,9 @@ func printpanics(p *_panic) { func gopanic(e interface{}) { gp := getg() if gp.m.curg != gp { + print("panic: ") + printany(e) + print("\n") gothrow("panic on m stack") } @@ -414,7 +418,7 @@ func gopanic(e interface{}) { // Pass information about recovering frame to recovery. gp.sigcode0 = uintptr(argp) gp.sigcode1 = pc - mcall(recovery_m) + mcall(recovery) gothrow("recovery failed") // mcall should not return } } |