diff options
author | Russ Cox <rsc@golang.org> | 2014-09-08 00:08:51 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-09-08 00:08:51 -0400 |
commit | 8528da672cc093d4dd06732819abc1f7b6b5a46e (patch) | |
tree | 334be80d4a4c85b77db6f6fdb67cbf0528cba5f5 /src/pkg/runtime/panic.go | |
parent | 73bcb69f272cbf34ddcc9daa56427a8683b5a95d (diff) | |
download | go-8528da672cc093d4dd06732819abc1f7b6b5a46e.tar.gz |
build: move package sources from src/pkg to src
Preparation was in CL 134570043.
This CL contains only the effect of 'hg mv src/pkg/* src'.
For more about the move, see golang.org/s/go14nopkg.
Diffstat (limited to 'src/pkg/runtime/panic.go')
-rw-r--r-- | src/pkg/runtime/panic.go | 216 |
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() -} |