summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/panic.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/panic.go')
-rw-r--r--src/pkg/runtime/panic.go216
1 files changed, 0 insertions, 216 deletions
diff --git a/src/pkg/runtime/panic.go b/src/pkg/runtime/panic.go
deleted file mode 100644
index 1e35561d1..000000000
--- a/src/pkg/runtime/panic.go
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2014 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.
-
-package runtime
-
-import "unsafe"
-
-var indexError = error(errorString("index out of range"))
-
-func panicindex() {
- panic(indexError)
-}
-
-var sliceError = error(errorString("slice bounds out of range"))
-
-func panicslice() {
- panic(sliceError)
-}
-
-var divideError = error(errorString("integer divide by zero"))
-
-func panicdivide() {
- panic(divideError)
-}
-
-func throwreturn() {
- gothrow("no return at end of a typed function - compiler is broken")
-}
-
-func throwinit() {
- gothrow("recursive call during initialization - linker skew")
-}
-
-// Create a new deferred function fn with siz bytes of arguments.
-// The compiler turns a defer statement into a call to this.
-//go:nosplit
-func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
- // 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
- // to somewhere safe. deferproc_m does that. Until deferproc_m,
- // we can only call nosplit routines.
- argp := uintptr(unsafe.Pointer(&fn))
- argp += unsafe.Sizeof(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)
-
- releasem(mp)
-
- // deferproc returns 0 normally.
- // a deferred func that stops a panic
- // makes the deferproc return 1.
- // the code the compiler generates always
- // checks the return value and jumps to the
- // end of the function if deferproc returns != 0.
- return0()
- // No code can go here - the C return register has
- // been set and must not be clobbered.
-}
-
-// Each P holds pool for defers with arg sizes 8, 24, 40, 56 and 72 bytes.
-// Memory block is 40 (24 for 32 bits) bytes larger due to Defer header.
-// This maps exactly to malloc size classes.
-
-// defer size class for arg size sz
-func deferclass(siz uintptr) uintptr {
- return (siz + 7) >> 4
-}
-
-// total size of memory block for defer with arg size sz
-func totaldefersize(siz uintptr) uintptr {
- return (unsafe.Sizeof(_defer{}) - unsafe.Sizeof(_defer{}.args)) + round(siz, ptrSize)
-}
-
-// Ensure that defer arg sizes that map to the same defer size class
-// also map to the same malloc size class.
-func testdefersizes() {
- var m [len(p{}.deferpool)]int32
-
- for i := range m {
- m[i] = -1
- }
- for i := uintptr(0); ; i++ {
- defersc := deferclass(i)
- if defersc >= uintptr(len(m)) {
- break
- }
- siz := goroundupsize(totaldefersize(i))
- if m[defersc] < 0 {
- m[defersc] = int32(siz)
- continue
- }
- if m[defersc] != int32(siz) {
- print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
- gothrow("bad defer size class")
- }
- }
-}
-
-// Allocate a Defer, usually using per-P pool.
-// Each defer must be released with freedefer.
-// Note: runs on M stack
-func newdefer(siz int32) *_defer {
- var d *_defer
- sc := deferclass(uintptr(siz))
- mp := acquirem()
- if sc < uintptr(len(p{}.deferpool)) {
- pp := mp.p
- d = pp.deferpool[sc]
- if d != nil {
- pp.deferpool[sc] = d.link
- }
- }
- if d == nil {
- // deferpool is empty or just a big defer
- total := goroundupsize(totaldefersize(uintptr(siz)))
- d = (*_defer)(gomallocgc(total, conservative, 0))
- }
- d.siz = siz
- d.special = false
- gp := mp.curg
- d.link = gp._defer
- gp._defer = d
- releasem(mp)
- return d
-}
-
-// Free the given defer.
-// The defer cannot be used after this call.
-func freedefer(d *_defer) {
- if d.special {
- return
- }
- sc := deferclass(uintptr(d.siz))
- if sc < uintptr(len(p{}.deferpool)) {
- mp := acquirem()
- pp := mp.p
- d.link = pp.deferpool[sc]
- pp.deferpool[sc] = d
- releasem(mp)
- // No need to wipe out pointers in argp/pc/fn/args,
- // because we empty the pool before GC.
- }
-}
-
-// Run a deferred function if there is one.
-// The compiler inserts a call to this at the end of any
-// function which calls defer.
-// If there is a deferred function, this will call runtime·jmpdefer,
-// which will jump to the deferred function such that it appears
-// to have been called by the caller of deferreturn at the point
-// just before deferreturn was called. The effect is that deferreturn
-// is called again and again until there are no more deferred functions.
-// Cannot split the stack because we reuse the caller's frame to
-// call the deferred function.
-
-// The single argument isn't actually used - it just has its address
-// taken so it can be matched against pending defers.
-//go:nosplit
-func deferreturn(arg0 uintptr) {
- gp := getg()
- d := gp._defer
- if d == nil {
- return
- }
- argp := uintptr(unsafe.Pointer(&arg0))
- if d.argp != argp {
- return
- }
-
- // Moving arguments around.
- // Do not allow preemption here, because the garbage collector
- // won't know the form of the arguments until the jmpdefer can
- // flip the PC over to fn.
- mp := acquirem()
- memmove(unsafe.Pointer(argp), unsafe.Pointer(&d.args), uintptr(d.siz))
- fn := d.fn
- gp._defer = d.link
- freedefer(d)
- releasem(mp)
- jmpdefer(fn, argp)
-}
-
-// Goexit terminates the goroutine that calls it. No other goroutine is affected.
-// Goexit runs all deferred calls before terminating the goroutine.
-//
-// Calling Goexit from the main goroutine terminates that goroutine
-// without func main returning. Since func main has not returned,
-// the program continues execution of other goroutines.
-// If all other goroutines exit, the program crashes.
-func Goexit() {
- // Run all deferred functions for the current goroutine.
- gp := getg()
- for gp._defer != nil {
- d := gp._defer
- gp._defer = d.link
- reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
- freedefer(d)
- // Note: we ignore recovers here because Goexit isn't a panic
- }
- goexit()
-}