mirror of
https://github.com/golang/go
synced 2024-09-24 05:20:13 -06:00
runtime: tidy cgocallback
On amd64 and 386, we have a very roundabout way of remembering that we need to dropm on return that currently involves saving a zero to needm's argument slot and later bringing it back. Just store the zero. This also makes amd64 and 386 more consistent with cgocallback on all other platforms: rather than saving the old M to the G stack, they now save it to a named slot on the G0 stack. The needm function no longer needs a dummy argument to get the SP, so we drop that. Change-Id: I7e84bb4a5ff9552de70dcf41d8accf02310535e7 Reviewed-on: https://go-review.googlesource.com/c/go/+/263268 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
30c1887873
commit
c91dffbc9a
@ -704,7 +704,7 @@ nosave:
|
||||
|
||||
// cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
|
||||
// See cgocall.go for more details.
|
||||
TEXT ·cgocallback(SB),NOSPLIT,$16-12 // Frame size must match commented places below
|
||||
TEXT ·cgocallback(SB),NOSPLIT,$12-12 // Frame size must match commented places below
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// If g is nil, Go did not create the current thread.
|
||||
@ -722,13 +722,12 @@ TEXT ·cgocallback(SB),NOSPLIT,$16-12 // Frame size must match commented places
|
||||
CMPL BP, $0
|
||||
JEQ needm
|
||||
MOVL g_m(BP), BP
|
||||
MOVL BP, DX // saved copy of oldm
|
||||
MOVL BP, savedm-4(SP) // saved copy of oldm
|
||||
JMP havem
|
||||
needm:
|
||||
MOVL $0, 0(SP)
|
||||
MOVL $runtime·needm(SB), AX
|
||||
CALL AX
|
||||
MOVL 0(SP), DX
|
||||
MOVL $0, savedm-4(SP) // dropm on return
|
||||
get_tls(CX)
|
||||
MOVL g(CX), BP
|
||||
MOVL g_m(BP), BP
|
||||
@ -769,8 +768,6 @@ havem:
|
||||
// Once we switch to the curg stack, the pushed PC will appear
|
||||
// to be the return PC of cgocallback, so that the traceback
|
||||
// will seamlessly trace back into the earlier calls.
|
||||
//
|
||||
// In the new goroutine, 12(SP) holds the saved oldm (DX) register.
|
||||
MOVL m_curg(BP), SI
|
||||
MOVL SI, g(CX)
|
||||
MOVL (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
|
||||
@ -780,20 +777,18 @@ havem:
|
||||
MOVL fn+0(FP), AX
|
||||
MOVL frame+4(FP), BX
|
||||
MOVL ctxt+8(FP), CX
|
||||
LEAL -(4+16)(DI), SP // Must match declared frame size
|
||||
MOVL DX, 12(SP)
|
||||
LEAL -(4+12)(DI), SP // Must match declared frame size
|
||||
MOVL AX, 0(SP)
|
||||
MOVL BX, 4(SP)
|
||||
MOVL CX, 8(SP)
|
||||
CALL runtime·cgocallbackg(SB)
|
||||
MOVL 12(SP), DX
|
||||
|
||||
// Restore g->sched (== m->curg->sched) from saved values.
|
||||
get_tls(CX)
|
||||
MOVL g(CX), SI
|
||||
MOVL 16(SP), BP // Must match declared frame size
|
||||
MOVL 12(SP), BP // Must match declared frame size
|
||||
MOVL BP, (g_sched+gobuf_pc)(SI)
|
||||
LEAL (16+4)(SP), DI // Must match declared frame size
|
||||
LEAL (12+4)(SP), DI // Must match declared frame size
|
||||
MOVL DI, (g_sched+gobuf_sp)(SI)
|
||||
|
||||
// Switch back to m->g0's stack and restore m->g0->sched.sp.
|
||||
@ -809,6 +804,7 @@ havem:
|
||||
|
||||
// If the m on entry was nil, we called needm above to borrow an m
|
||||
// for the duration of the call. Since the call is over, return it with dropm.
|
||||
MOVL savedm-4(SP), DX
|
||||
CMPL DX, $0
|
||||
JNE 3(PC)
|
||||
MOVL $runtime·dropm(SB), AX
|
||||
|
@ -693,7 +693,7 @@ nosave:
|
||||
|
||||
// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
|
||||
// See cgocall.go for more details.
|
||||
TEXT ·cgocallback(SB),NOSPLIT,$32-24
|
||||
TEXT ·cgocallback(SB),NOSPLIT,$24-24
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// If g is nil, Go did not create the current thread.
|
||||
@ -711,13 +711,12 @@ TEXT ·cgocallback(SB),NOSPLIT,$32-24
|
||||
CMPQ BX, $0
|
||||
JEQ needm
|
||||
MOVQ g_m(BX), BX
|
||||
MOVQ BX, R8 // holds oldm until end of function
|
||||
MOVQ BX, savedm-8(SP) // saved copy of oldm
|
||||
JMP havem
|
||||
needm:
|
||||
MOVQ $0, 0(SP)
|
||||
MOVQ $runtime·needm(SB), AX
|
||||
MOVQ $runtime·needm(SB), AX
|
||||
CALL AX
|
||||
MOVQ 0(SP), R8
|
||||
MOVQ $0, savedm-8(SP) // dropm on return
|
||||
get_tls(CX)
|
||||
MOVQ g(CX), BX
|
||||
MOVQ g_m(BX), BX
|
||||
@ -758,8 +757,6 @@ havem:
|
||||
// Once we switch to the curg stack, the pushed PC will appear
|
||||
// to be the return PC of cgocallback, so that the traceback
|
||||
// will seamlessly trace back into the earlier calls.
|
||||
//
|
||||
// In the new goroutine, 24(SP) holds the saved R8.
|
||||
MOVQ m_curg(BX), SI
|
||||
MOVQ SI, g(CX)
|
||||
MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
|
||||
@ -776,12 +773,10 @@ havem:
|
||||
SUBQ AX, DI // Allocate the same frame size on the g stack
|
||||
MOVQ DI, SP
|
||||
|
||||
MOVQ R8, 24(SP)
|
||||
MOVQ BX, 0(SP)
|
||||
MOVQ CX, 8(SP)
|
||||
MOVQ DX, 16(SP)
|
||||
CALL runtime·cgocallbackg(SB)
|
||||
MOVQ 24(SP), R8
|
||||
|
||||
// Compute the size of the frame again. FP and SP have
|
||||
// completely different values here than they did above,
|
||||
@ -811,7 +806,8 @@ havem:
|
||||
|
||||
// If the m on entry was nil, we called needm above to borrow an m
|
||||
// for the duration of the call. Since the call is over, return it with dropm.
|
||||
CMPQ R8, $0
|
||||
MOVQ savedm-8(SP), BX
|
||||
CMPQ BX, $0
|
||||
JNE 3(PC)
|
||||
MOVQ $runtime·dropm(SB), AX
|
||||
CALL AX
|
||||
|
@ -1695,7 +1695,7 @@ func allocm(_p_ *p, fn func(), id int64) *m {
|
||||
// When the callback is done with the m, it calls dropm to
|
||||
// put the m back on the list.
|
||||
//go:nosplit
|
||||
func needm(x byte) {
|
||||
func needm() {
|
||||
if (iscgo || GOOS == "windows") && !cgoHasExtraM {
|
||||
// Can happen if C/C++ code calls Go from a global ctor.
|
||||
// Can also happen on Windows if a global ctor uses a
|
||||
@ -1740,8 +1740,8 @@ func needm(x byte) {
|
||||
// which is more than enough for us.
|
||||
setg(mp.g0)
|
||||
_g_ := getg()
|
||||
_g_.stack.hi = uintptr(noescape(unsafe.Pointer(&x))) + 1024
|
||||
_g_.stack.lo = uintptr(noescape(unsafe.Pointer(&x))) - 32*1024
|
||||
_g_.stack.hi = getcallersp() + 1024
|
||||
_g_.stack.lo = getcallersp() - 32*1024
|
||||
_g_.stackguard0 = _g_.stack.lo + _StackGuard
|
||||
|
||||
// Initialize this thread to use the m.
|
||||
|
@ -504,14 +504,14 @@ func adjustSignalStack(sig uint32, mp *m, gsigStack *gsignalStack) bool {
|
||||
sigaltstack(nil, &st)
|
||||
if st.ss_flags&_SS_DISABLE != 0 {
|
||||
setg(nil)
|
||||
needm(0)
|
||||
needm()
|
||||
noSignalStack(sig)
|
||||
dropm()
|
||||
}
|
||||
stsp := uintptr(unsafe.Pointer(st.ss_sp))
|
||||
if sp < stsp || sp >= stsp+st.ss_size {
|
||||
setg(nil)
|
||||
needm(0)
|
||||
needm()
|
||||
sigNotOnStack(sig)
|
||||
dropm()
|
||||
}
|
||||
@ -951,7 +951,7 @@ func badsignal(sig uintptr, c *sigctxt) {
|
||||
exit(2)
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
|
||||
}
|
||||
needm(0)
|
||||
needm()
|
||||
if !sigsend(uint32(sig)) {
|
||||
// A foreign thread received the signal sig, and the
|
||||
// Go code does not want to handle it.
|
||||
|
Loading…
Reference in New Issue
Block a user