]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: tidy cgocallback
authorAustin Clements <austin@google.com>
Thu, 8 Oct 2020 02:53:52 +0000 (22:53 -0400)
committerAustin Clements <austin@google.com>
Mon, 26 Oct 2020 14:50:34 +0000 (14:50 +0000)
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>
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/proc.go
src/runtime/signal_unix.go

index a54b68e03d9d03c5cfffe1e856f4d8c4f4cca228..fa3b1be3392598526a34281624482662069921be 100644 (file)
@@ -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
index 3d5d9c4d583f6d84eab229f63ced1831e69862f9..19a3bb2d7d3cdad648541c3ebc7d456120fc9d3c 100644 (file)
@@ -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
index c629fd45f09df1cf194956e6c71ede9536f0a106..ec4e6d875128f48cc52107c3ecf5cc2f49d1a0ef 100644 (file)
@@ -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.
index e8b6f95d8f6256f4703e8d3883d749d95b487c29..9318a9b8bc51370aef3c066fda3c24ffadce6b9e 100644 (file)
@@ -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.