Skip to content

Commit cb76724

Browse files
committed
runtime: refactor/fix asmcgocall/asmcgocall_errno
Instead of making asmcgocall call asmcgocall_errno, make both load args into registers and call a shared assembly function. On amd64, this costs 1 word in the asmcgocall_errno path but saves 3 words in the asmcgocall path, and the latter is what happens on critical nosplit paths on Windows. On arm, this fixes build failures: asmcgocall was writing the arguments for asmcgocall_errno into the wrong place on the stack. Passing them in registers avoids the decision entirely. On 386, this isn't really needed, since the nosplit paths have twice as many words to work with, but do it for consistency. Update #8635 Fixes arm build (except GOARM=5). TBR=iant CC=golang-codereviews https://golang.org/cl/134390043
1 parent f403416 commit cb76724

File tree

4 files changed

+32
-18
lines changed

4 files changed

+32
-18
lines changed

misc/cgo/test/callback.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ func testCallbackCallers(t *testing.T) {
156156
"runtime.cgocallbackg1",
157157
"runtime.cgocallbackg",
158158
"runtime.cgocallback_gofunc",
159+
"asmcgocall",
159160
"runtime.asmcgocall_errno",
160161
"runtime.cgocall_errno",
161162
"test._Cfunc_callback",
@@ -182,8 +183,12 @@ func testCallbackCallers(t *testing.T) {
182183
if strings.HasPrefix(fname, "_") {
183184
fname = path.Base(f.Name()[1:])
184185
}
185-
if fname != name[i] {
186-
t.Errorf("expected function name %s, got %s", name[i], fname)
186+
namei := ""
187+
if i < len(name) {
188+
namei = name[i]
189+
}
190+
if fname != namei {
191+
t.Errorf("stk[%d] = %q, want %q", i, fname, namei)
187192
}
188193
}
189194
}

src/pkg/runtime/asm_386.s

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -680,17 +680,21 @@ TEXT gosave<>(SB),NOSPLIT,$0
680680
// Call fn(arg) on the scheduler stack,
681681
// aligned appropriately for the gcc ABI.
682682
// See cgocall.c for more details.
683-
TEXT runtime·asmcgocall(SB),NOSPLIT,$12-8
683+
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
684684
MOVL fn+0(FP), AX
685685
MOVL arg+4(FP), BX
686-
MOVL AX, 0(SP)
687-
MOVL BX, 4(SP)
688-
CALL runtime·asmcgocall_errno(SB)
686+
CALL asmcgocall<>(SB)
689687
RET
690688

691689
TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
692690
MOVL fn+0(FP), AX
693691
MOVL arg+4(FP), BX
692+
CALL asmcgocall<>(SB)
693+
MOVL AX, ret+8(FP)
694+
RET
695+
696+
TEXT asmcgocall<>(SB),NOSPLIT,$0-12
697+
// fn in AX, arg in BX
694698
MOVL SP, DX
695699

696700
// Figure out if we need to switch to m->g0 stack.
@@ -720,7 +724,6 @@ TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
720724
MOVL 8(SP), DI
721725
MOVL DI, g(CX)
722726
MOVL 4(SP), SP
723-
MOVL AX, ret+8(FP)
724727
RET
725728

726729
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)

src/pkg/runtime/asm_amd64.s

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -764,17 +764,21 @@ TEXT gosave<>(SB),NOSPLIT,$0
764764
// Call fn(arg) on the scheduler stack,
765765
// aligned appropriately for the gcc ABI.
766766
// See cgocall.c for more details.
767-
TEXT runtime·asmcgocall(SB),NOSPLIT,$24-16
767+
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
768768
MOVQ fn+0(FP), AX
769769
MOVQ arg+8(FP), BX
770-
MOVQ AX, 0(SP)
771-
MOVQ BX, 8(SP)
772-
CALL runtime·asmcgocall_errno(SB)
770+
CALL asmcgocall<>(SB)
773771
RET
774772

775773
TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-20
776774
MOVQ fn+0(FP), AX
777775
MOVQ arg+8(FP), BX
776+
CALL asmcgocall<>(SB)
777+
MOVL AX, ret+16(FP)
778+
RET
779+
780+
// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.
781+
TEXT asmcgocall<>(SB),NOSPLIT,$0-0
778782
MOVQ SP, DX
779783

780784
// Figure out if we need to switch to m->g0 stack.
@@ -813,7 +817,6 @@ nosave:
813817
MOVQ 48(SP), DI
814818
MOVQ DI, g(CX)
815819
MOVQ 40(SP), SP
816-
MOVL AX, ret+16(FP)
817820
RET
818821

819822
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)

src/pkg/runtime/asm_arm.s

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -493,17 +493,21 @@ TEXT gosave<>(SB),NOSPLIT,$0
493493
// Call fn(arg) on the scheduler stack,
494494
// aligned appropriately for the gcc ABI.
495495
// See cgocall.c for more details.
496-
TEXT runtime·asmcgocall(SB),NOSPLIT,$12-8
496+
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
497497
MOVW fn+0(FP), R1
498-
MOVW arg+4(FP), R2
499-
MOVW R1, 0(R13)
500-
MOVW R2, 4(R13)
501-
BL runtime·asmcgocall_errno(SB)
498+
MOVW arg+4(FP), R0
499+
BL asmcgocall<>(SB)
502500
RET
503501

504502
TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
505503
MOVW fn+0(FP), R1
506504
MOVW arg+4(FP), R0
505+
BL asmcgocall<>(SB)
506+
MOVW R0, ret+8(FP)
507+
RET
508+
509+
TEXT asmcgocall<>(SB),NOSPLIT,$0-0
510+
// fn in R1, arg in R0.
507511
MOVW R13, R2
508512
MOVW g, R5
509513

@@ -529,7 +533,6 @@ TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
529533
// Restore registers, g, stack pointer.
530534
MOVW 20(R13), g
531535
MOVW 16(R13), R13
532-
MOVW R0, ret+8(FP)
533536
RET
534537

535538
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)

0 commit comments

Comments
 (0)