// 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.
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
// 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
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.
// 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
// 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.
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
// 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
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,
// 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
// 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
// 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.
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()
}
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.