runtime: make asmcgocall g0/gsignal checks consistent

In asmcgocall() we need to switch to the g0 stack if we're not already on
the g0 stack or the gsignal stack. The prefered way of doing this is to
check gsignal first, then g0, since if we are going to switch to g0 we will
need g0 handy (thus avoiding a second load).

Rewrite/reorder 386 and amd64 to check gsignal first - this shaves a few
assembly instructions off and makes the order consistent with arm, arm64,
mips64 and ppc64. Add missing gsignal checks to mips, riscv64 and s390x.

Change-Id: I1b027bf393c25e0c33e1d8eb80de67e4a0a3f561
Reviewed-on: https://go-review.googlesource.com/c/go/+/335869
Trust: Joel Sing <joel@sing.id.au>
Run-TryBot: Joel Sing <joel@sing.id.au>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Joel Sing 2021-07-20 17:29:15 +10:00
parent 160d797260
commit fcdc3c098c
9 changed files with 39 additions and 29 deletions

View File

@ -633,18 +633,18 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
get_tls(CX) get_tls(CX)
MOVL g(CX), BP
CMPL BP, $0
JEQ nosave // Don't even have a G yet.
MOVL g_m(BP), BP
MOVL m_g0(BP), SI
MOVL g(CX), DI MOVL g(CX), DI
CMPL SI, DI CMPL DI, $0
JEQ noswitch JEQ nosave // Don't even have a G yet.
MOVL g_m(DI), BP
CMPL DI, m_gsignal(BP) CMPL DI, m_gsignal(BP)
JEQ noswitch JEQ noswitch
MOVL m_g0(BP), SI
CMPL DI, SI
JEQ noswitch
CALL gosave_systemstack_switch<>(SB) CALL gosave_systemstack_switch<>(SB)
get_tls(CX) get_tls(CX)
MOVL SI, g(CX) MOVL SI, g(CX)

View File

@ -667,22 +667,21 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
get_tls(CX) get_tls(CX)
MOVQ g(CX), R8
CMPQ R8, $0
JEQ nosave
MOVQ g_m(R8), R8
MOVQ m_g0(R8), SI
MOVQ g(CX), DI MOVQ g(CX), DI
CMPQ SI, DI CMPQ DI, $0
JEQ nosave JEQ nosave
MOVQ g_m(DI), R8
MOVQ m_gsignal(R8), SI MOVQ m_gsignal(R8), SI
CMPQ SI, DI CMPQ DI, SI
JEQ nosave
MOVQ m_g0(R8), SI
CMPQ DI, SI
JEQ nosave JEQ nosave
// Switch to system stack. // Switch to system stack.
MOVQ m_g0(R8), SI
CALL gosave_systemstack_switch<>(SB) CALL gosave_systemstack_switch<>(SB)
MOVQ SI, g(CX) MOVQ SI, g(CX)
MOVQ (g_sched+gobuf_sp)(SI), SP MOVQ (g_sched+gobuf_sp)(SI), SP

View File

@ -556,7 +556,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
MOVW g_m(g), R8 MOVW g_m(g), R8
MOVW m_gsignal(R8), R3 MOVW m_gsignal(R8), R3
CMP R3, g CMP R3, g

View File

@ -1027,7 +1027,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
MOVD g_m(g), R8 MOVD g_m(g), R8
MOVD m_gsignal(R8), R3 MOVD m_gsignal(R8), R3
CMP R3, g CMP R3, g

View File

@ -424,7 +424,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
MOVV g_m(g), R5 MOVV g_m(g), R5
MOVV m_gsignal(R5), R6 MOVV m_gsignal(R5), R6
BEQ R6, g, g0 BEQ R6, g, g0

View File

@ -413,8 +413,11 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
MOVW g_m(g), R5 MOVW g_m(g), R5
MOVW m_gsignal(R5), R6
BEQ R6, g, g0
MOVW m_g0(R5), R6 MOVW m_g0(R5), R6
BEQ R6, g, g0 BEQ R6, g, g0

View File

@ -541,9 +541,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// Moreover, if it's called inside the signal handler, it must not switch // be on the m->gsignal stack.
// to g0 as it can be in use by another syscall.
MOVD g_m(g), R8 MOVD g_m(g), R8
MOVD m_gsignal(R8), R6 MOVD m_gsignal(R8), R6
CMP R6, g CMP R6, g

View File

@ -310,8 +310,11 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
MOV g_m(g), X6 MOV g_m(g), X6
MOV m_gsignal(X6), X7
BEQ X7, g, g0
MOV m_g0(X6), X7 MOV m_g0(X6), X7
BEQ X7, g, g0 BEQ X7, g, g0

View File

@ -513,12 +513,15 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those // We get called to create new OS threads too, and those
// come in on the m->g0 stack already. // come in on the m->g0 stack already. Or we might already
// be on the m->gsignal stack.
MOVD g_m(g), R6 MOVD g_m(g), R6
MOVD m_g0(R6), R6 MOVD m_gsignal(R6), R7
CMPBEQ R6, g, g0 CMPBEQ R7, g, g0
MOVD m_g0(R6), R7
CMPBEQ R7, g, g0
BL gosave_systemstack_switch<>(SB) BL gosave_systemstack_switch<>(SB)
MOVD R6, g MOVD R7, g
BL runtime·save_g(SB) BL runtime·save_g(SB)
MOVD (g_sched+gobuf_sp)(g), R15 MOVD (g_sched+gobuf_sp)(g), R15