]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: implement osyield in Go instead of assembly on Windows
authorqmuntal <quimmuntal@gmail.com>
Thu, 7 Sep 2023 10:41:37 +0000 (12:41 +0200)
committerQuim Muntal <quimmuntal@gmail.com>
Wed, 20 Sep 2023 16:15:50 +0000 (16:15 +0000)
Windows APIs are normally not arch-specific, so it's better to
implement them in Go instead of assembly.

It was previously implemented in assembly because it was the only way
to support calls without a valid g. This CL defines a new function,
stdcall_no_g, that can be used in such cases.

Change-Id: I26a223b918c6c462b06ac256bdacf9ddb78752bc
Reviewed-on: https://go-review.googlesource.com/c/go/+/526476
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/runtime/os_windows.go
src/runtime/sys_windows_386.s
src/runtime/sys_windows_amd64.s
src/runtime/sys_windows_arm.s
src/runtime/sys_windows_arm64.s

index e52f9e6bd53efb890fa66c8a54d4ec7f14bed0ba..576988e107717458f0222a7d51455f48f5c7755f 100644 (file)
@@ -955,6 +955,22 @@ func mdestroy(mp *m) {
        }
 }
 
+// asmstdcall_trampoline calls asmstdcall converting from Go to C calling convention.
+func asmstdcall_trampoline(args unsafe.Pointer)
+
+// stdcall_no_g calls asmstdcall on os stack without using g.
+//
+//go:nosplit
+func stdcall_no_g(fn stdFunction, n int, args uintptr) uintptr {
+       libcall := libcall{
+               fn:   uintptr(unsafe.Pointer(fn)),
+               n:    uintptr(n),
+               args: args,
+       }
+       asmstdcall_trampoline(noescape(unsafe.Pointer(&libcall)))
+       return libcall.r1
+}
+
 // Calling stdcall on os stack.
 // May run during STW, so write barriers are not allowed.
 //
@@ -1054,16 +1070,17 @@ func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
 
 // These must run on the system stack only.
 func usleep2(dt int32)
-func switchtothread()
 
 //go:nosplit
 func osyield_no_g() {
-       switchtothread()
+       stdcall_no_g(_SwitchToThread, 0, 0)
 }
 
 //go:nosplit
 func osyield() {
-       systemstack(switchtothread)
+       systemstack(func() {
+               stdcall0(_SwitchToThread)
+       })
 }
 
 //go:nosplit
index 2efde4515bec5d6ea7ad02f88d15f02c3b4470cc..c8d4bf93a7a5c8aa6c7a5a63a96b54ee8b3a17a6 100644 (file)
@@ -11,6 +11,9 @@
 #define TEB_TlsSlots 0xE10
 #define TEB_ArbitraryPtr 0x14
 
+TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
+       JMP     runtime·asmstdcall(SB)
+
 // void runtime·asmstdcall(void *c);
 TEXT runtime·asmstdcall(SB),NOSPLIT,$0
        MOVL    fn+0(FP), BX
@@ -248,14 +251,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20-4
        MOVL    BP, SP
        RET
 
-// Runs on OS stack.
-TEXT runtime·switchtothread(SB),NOSPLIT,$0
-       MOVL    SP, BP
-       MOVL    runtime·_SwitchToThread(SB), AX
-       CALL    AX
-       MOVL    BP, SP
-       RET
-
 TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
 loop:
        MOVL    (_INTERRUPT_TIME+time_hi1), AX
index 7a7905e56a3a8f8bf9f2f551e7d9ce2f30b1ae20..af2b52735d9afe57ad8db53d531bef7b4f7435ad 100644 (file)
 #define TEB_TlsSlots 0x1480
 #define TEB_ArbitraryPtr 0x28
 
+TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
+       MOVQ    AX, CX
+       JMP     runtime·asmstdcall(SB)
+
 // void runtime·asmstdcall(void *c);
 TEXT runtime·asmstdcall(SB),NOSPLIT,$16
        MOVQ    SP, AX
@@ -258,18 +262,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$48-4
        MOVQ    40(SP), SP
        RET
 
-// Runs on OS stack.
-TEXT runtime·switchtothread(SB),NOSPLIT,$0
-       MOVQ    SP, AX
-       ANDQ    $~15, SP        // alignment as per Windows requirement
-       SUBQ    $(48), SP       // room for SP and 4 args as per Windows requirement
-                               // plus one extra word to keep stack 16 bytes aligned
-       MOVQ    AX, 32(SP)
-       MOVQ    runtime·_SwitchToThread(SB), AX
-       CALL    AX
-       MOVQ    32(SP), SP
-       RET
-
 TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
        MOVQ    $_INTERRUPT_TIME, DI
        MOVQ    time_lo(DI), AX
index c9fca19981bb1c161d22e5ae5bd80348f4e95c35..4b941e40ae59bfc3223c74fc27cce5c25c6b9289 100644 (file)
@@ -9,6 +9,9 @@
 
 // Note: For system ABI, R0-R3 are args, R4-R11 are callee-save.
 
+TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
+       B       runtime·asmstdcall(SB)
+
 // void runtime·asmstdcall(void *c);
 TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
        MOVM.DB.W [R4, R5, R14], (R13)  // push {r4, r5, lr}
@@ -211,16 +214,6 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$0-4
        MOVW    R4, R13                 // Restore SP
        MOVM.IA.W (R13), [R4, R15]      // pop {R4, pc}
 
-// Runs on OS stack.
-TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
-       MOVM.DB.W [R4, R14], (R13)      // push {R4, lr}
-       MOVW    R13, R4
-       BIC     $0x7, R13               // alignment for ABI
-       MOVW    runtime·_SwitchToThread(SB), R0
-       BL      (R0)
-       MOVW    R4, R13                 // restore stack pointer
-       MOVM.IA.W (R13), [R4, R15]      // pop {R4, pc}
-
 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
        B       runtime·armPublicationBarrier(SB)
 
index 2781c3c7d09cf9385614ba8564db35bb40dc3c25..4818994ed4882d9a72593d8a8146493bf34b66cc 100644 (file)
@@ -19,6 +19,9 @@
 //
 // load_g and save_g (in tls_arm64.s) clobber R27 (REGTMP) and R0.
 
+TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
+       B       runtime·asmstdcall(SB)
+
 // void runtime·asmstdcall(void *c);
 TEXT runtime·asmstdcall(SB),NOSPLIT,$16
        STP     (R19, R20), 16(RSP) // save old R19, R20
@@ -240,14 +243,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$32-4
        ADD     $16, RSP
        RET
 
-// Runs on OS stack.
-TEXT runtime·switchtothread(SB),NOSPLIT,$16-0
-       MOVD    runtime·_SwitchToThread(SB), R0
-       SUB     $16, RSP        // skip over saved frame pointer below RSP
-       BL      (R0)
-       ADD     $16, RSP
-       RET
-
 TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
        MOVD    $_INTERRUPT_TIME, R3
        MOVD    time_lo(R3), R0