]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add a constant for the smallest possible stack frame
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Thu, 8 Oct 2015 08:52:03 +0000 (21:52 +1300)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Sun, 18 Oct 2015 22:14:00 +0000 (22:14 +0000)
Shared libraries on ppc64le will require a larger minimum stack frame (because
the ABI mandates that the TOC pointer is available at 24(R1)). So to prepare
for this, make a constant for the fixed part of a stack and use that where
necessary.

Change-Id: I447949f4d725003bb82e7d2cf7991c1bca5aa887
Reviewed-on: https://go-review.googlesource.com/15523
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

14 files changed:
src/runtime/arch_386.go
src/runtime/arch_amd64.go
src/runtime/arch_amd64p32.go
src/runtime/arch_arm.go
src/runtime/arch_arm64.go
src/runtime/arch_ppc64.go
src/runtime/arch_ppc64le.go
src/runtime/cgocall.go
src/runtime/mgcmark.go
src/runtime/panic.go
src/runtime/proc1.go
src/runtime/signal_ppc64x.go
src/runtime/stack.go
src/runtime/traceback.go

index 4ab00c33964812bd1011f1094bbcfa9e78901d68..75e94eccfd16e5a7a8f5c5ce5cd059d6b9f51c13 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 1
        _Int64Align    = 4
        hugePageSize   = 1 << 21
+       minFrameSize   = 0
 )
 
 type uintreg uint32
index b2ca077e4fb21762bacb7b7dc156c9f98ebccb9f..d7721f74a185d8c6712cc0c432fe9332c754b3f6 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 1
        _Int64Align    = 8
        hugePageSize   = 1 << 21
+       minFrameSize   = 0
 )
 
 type uintreg uint64
index 3f66822445a586f158e3ef6b9e3e2320d3181dd7..aa8343ac22a6108ca37f99e6a8570c94617ab5aa 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 1
        _Int64Align    = 8
        hugePageSize   = 1 << 21
+       minFrameSize   = 0
 )
 
 type uintreg uint64
index d5d57703f68efdffc0ed1063e96cbb4f07a726c2..aa3e180c57ae2e257cddc5906ca84f16eef3e147 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 4
        _Int64Align    = 4
        hugePageSize   = 0
+       minFrameSize   = 4
 )
 
 type uintreg uint32
index f26227a557a68ed1387f04e25e286408f7c21c25..f01c26d5aedf851306ffb4b7bf2072e9910d6dcd 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 4
        _Int64Align    = 8
        hugePageSize   = 0
+       minFrameSize   = 8
 )
 
 type uintreg uint64
index a2cd85c1293ea556c2fefbf313a1c480f7cd226d..273cc564ed92692386979904afcb060f089658a8 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 4
        _Int64Align    = 8
        hugePageSize   = 0
+       minFrameSize   = 8
 )
 
 type uintreg uint64
index 4f89da337f5671ef307b4b7928199e0418031a13..e4eb9e5d8ae59a618f98909ec532980bd7496d18 100644 (file)
@@ -12,6 +12,7 @@ const (
        _PCQuantum     = 4
        _Int64Align    = 8
        hugePageSize   = 0
+       minFrameSize   = 8
 )
 
 type uintreg uint64
index f09a66a07d0e3deab1aef43c0f47a8225fc314a0..d39e6602465aead2657374d7000921d58b5e649e 100644 (file)
@@ -237,10 +237,22 @@ func cgocallbackg1() {
                // On 386, stack frame is three words, plus caller PC.
                cb = (*args)(unsafe.Pointer(sp + 4*ptrSize))
        case "ppc64", "ppc64le":
-               // On ppc64, stack frame is two words and there's a
-               // saved LR between SP and the stack frame and between
-               // the stack frame and the arguments.
-               cb = (*args)(unsafe.Pointer(sp + 4*ptrSize))
+               // On ppc64, the callback arguments are in the arguments area of
+               // cgocallback's stack frame. The stack looks like this:
+               // +--------------------+------------------------------+
+               // |                    | ...                          |
+               // | cgoexp_$fn         +------------------------------+
+               // |                    | fixed frame area             |
+               // +--------------------+------------------------------+
+               // |                    | arguments area               |
+               // | cgocallback        +------------------------------+ <- sp + 2*minFrameSize + 2*ptrSize
+               // |                    | fixed frame area             |
+               // +--------------------+------------------------------+ <- sp + minFrameSize + 2*ptrSize
+               // |                    | local variables (2 pointers) |
+               // | cgocallback_gofunc +------------------------------+ <- sp + minFrameSize
+               // |                    | fixed frame area             |
+               // +--------------------+------------------------------+ <- sp
+               cb = (*args)(unsafe.Pointer(sp + 2*minFrameSize + 2*ptrSize))
        }
 
        // Invoke callback.
@@ -271,14 +283,10 @@ func unwindm(restore *bool) {
        switch GOARCH {
        default:
                throw("unwindm not implemented")
-       case "386", "amd64":
-               sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp))
-       case "arm":
-               sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 4))
+       case "386", "amd64", "arm", "ppc64", "ppc64le":
+               sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + minFrameSize))
        case "arm64":
                sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 16))
-       case "ppc64", "ppc64le":
-               sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 8))
        }
        releasem(mp)
 }
index 498c355fe8811308b623f2307589237ef3fe6084..95586dc74ef9f5016db5e2b24d1a57b5838c915c 100644 (file)
@@ -496,12 +496,10 @@ func scanframeworker(frame *stkframe, unused unsafe.Pointer, gcw *gcWork) {
        size := frame.varp - frame.sp
        var minsize uintptr
        switch thechar {
-       case '6', '8':
-               minsize = 0
        case '7':
                minsize = spAlign
        default:
-               minsize = ptrSize
+               minsize = minFrameSize
        }
        if size > minsize {
                stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
index 320c174829c283a2ca72dd2e3463d2c4c9991fe5..24431c86dc1bd1525ac853583fe0771286f2b84a 100644 (file)
@@ -531,8 +531,6 @@ func throw(s string) {
 //uint32 runtime·panicking;
 var paniclk mutex
 
-const hasLinkRegister = GOARCH == "arm" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le"
-
 // Unwind the stack after a deferred function calls recover
 // after a panic.  Then arrange to continue running as though
 // the caller of the deferred function returned normally.
index 614de5110c470c77b8e427ca989d15c99c965013..ef28467dfbf4713e07d61699fc54c3049ea52644 100644 (file)
@@ -2256,17 +2256,14 @@ func newproc1(fn *funcval, argp *uint8, narg int32, nret int32, callerpc uintptr
                throw("newproc1: new g is not Gdead")
        }
 
-       totalSize := 4*regSize + uintptr(siz) // extra space in case of reads slightly beyond frame
-       if hasLinkRegister {
-               totalSize += ptrSize
-       }
-       totalSize += -totalSize & (spAlign - 1) // align to spAlign
+       totalSize := 4*regSize + uintptr(siz) + minFrameSize // extra space in case of reads slightly beyond frame
+       totalSize += -totalSize & (spAlign - 1)              // align to spAlign
        sp := newg.stack.hi - totalSize
        spArg := sp
-       if hasLinkRegister {
+       if usesLR {
                // caller's LR
                *(*unsafe.Pointer)(unsafe.Pointer(sp)) = nil
-               spArg += ptrSize
+               spArg += minFrameSize
        }
        memmove(unsafe.Pointer(spArg), unsafe.Pointer(argp), uintptr(narg))
 
index bad9fe6de401a05b0b7a9dd7ea1387e861ab419c..71055b6bdbbb1c3bc55830c4b0cac9feae3d5cf3 100644 (file)
@@ -82,7 +82,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
                // functions are correctly handled. This smashes
                // the stack frame but we're not going back there
                // anyway.
-               sp := c.sp() - ptrSize
+               sp := c.sp() - minFrameSize
                c.set_sp(sp)
                *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
 
index 24d37271b4d615efd8c01f63d3280eeaeb0b825a..1809a4d9acf6cb81fe2e4f15ca82ad15ba68900c 100644 (file)
@@ -578,12 +578,10 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
        size := frame.varp - frame.sp
        var minsize uintptr
        switch thechar {
-       case '6', '8':
-               minsize = 0
        case '7':
                minsize = spAlign
        default:
-               minsize = ptrSize
+               minsize = minFrameSize
        }
        if size > minsize {
                var bv bitvector
index 544ce273ee28a0e8be6874508564ced75446d596..2d223ced62b67a504fd13e260cb8990dafcabd50 100644 (file)
@@ -26,9 +26,10 @@ import "unsafe"
 // stores an 8-byte return PC onto the stack. To accommodate this, we use regSize
 // as the size of the architecture-pushed return PC.
 //
-// usesLR is defined below. ptrSize and regSize are defined in stubs.go.
+// usesLR is defined below in terms of minFrameSize, which is defined in
+// arch_$GOARCH.go. ptrSize and regSize are defined in stubs.go.
 
-const usesLR = GOARCH != "amd64" && GOARCH != "amd64p32" && GOARCH != "386"
+const usesLR = minFrameSize > 0
 
 var (
        // initialized in tracebackinit
@@ -295,10 +296,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                // in package runtime and reflect, and for those we use call-specific
                // metadata recorded by f's caller.
                if callback != nil || printing {
-                       frame.argp = frame.fp
-                       if usesLR {
-                               frame.argp += ptrSize
-                       }
+                       frame.argp = frame.fp + minFrameSize
                        setArgInfo(&frame, f, callback != nil)
                }
 
@@ -396,7 +394,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                // before faking a call to sigpanic.
                if usesLR && waspanic {
                        x := *(*uintptr)(unsafe.Pointer(frame.sp))
-                       frame.sp += ptrSize
+                       frame.sp += minFrameSize
                        if GOARCH == "arm64" {
                                // arm64 needs 16-byte aligned SP, always
                                frame.sp += ptrSize
@@ -496,10 +494,7 @@ func setArgInfo(frame *stkframe, f *_func, needArgMap bool) {
                // Extract argument bitmaps for reflect stubs from the calls they made to reflect.
                switch funcname(f) {
                case "reflect.makeFuncStub", "reflect.methodValueCall":
-                       arg0 := frame.sp
-                       if usesLR {
-                               arg0 += ptrSize
-                       }
+                       arg0 := frame.sp + minFrameSize
                        fn := *(**[2]uintptr)(unsafe.Pointer(arg0))
                        if fn[0] != f.entry {
                                print("runtime: confused by ", funcname(f), "\n")