summaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-11-11 17:04:34 -0500
committerRuss Cox <rsc@golang.org>2014-11-11 17:04:34 -0500
commitbb9ee976541b2f008a1d1ded4bab7d823b313a53 (patch)
treea54192d2667891e2db5872bcbc150ea54db4e8ed /src/runtime/panic.go
parent6f55366e3789180fe24870e9ae8b064dae7d5f50 (diff)
downloadgo-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.go36
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
}
}