mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: add a constant for the smallest possible stack frame
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>
This commit is contained in:
parent
45c06b27a4
commit
a4855812e2
14 changed files with 38 additions and 37 deletions
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 1
|
||||
_Int64Align = 4
|
||||
hugePageSize = 1 << 21
|
||||
minFrameSize = 0
|
||||
)
|
||||
|
||||
type uintreg uint32
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 1
|
||||
_Int64Align = 8
|
||||
hugePageSize = 1 << 21
|
||||
minFrameSize = 0
|
||||
)
|
||||
|
||||
type uintreg uint64
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 1
|
||||
_Int64Align = 8
|
||||
hugePageSize = 1 << 21
|
||||
minFrameSize = 0
|
||||
)
|
||||
|
||||
type uintreg uint64
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 4
|
||||
_Int64Align = 4
|
||||
hugePageSize = 0
|
||||
minFrameSize = 4
|
||||
)
|
||||
|
||||
type uintreg uint32
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 4
|
||||
_Int64Align = 8
|
||||
hugePageSize = 0
|
||||
minFrameSize = 8
|
||||
)
|
||||
|
||||
type uintreg uint64
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 4
|
||||
_Int64Align = 8
|
||||
hugePageSize = 0
|
||||
minFrameSize = 8
|
||||
)
|
||||
|
||||
type uintreg uint64
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const (
|
|||
_PCQuantum = 4
|
||||
_Int64Align = 8
|
||||
hugePageSize = 0
|
||||
minFrameSize = 8
|
||||
)
|
||||
|
||||
type uintreg uint64
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 := 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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue