Skip to content

Commit

Permalink
runtime: refactor/fix asmcgocall/asmcgocall_errno
Browse files Browse the repository at this point in the history
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 golang#8635
Fixes arm build (except GOARM=5).

TBR=iant
CC=golang-codereviews
https://golang.org/cl/134390043
  • Loading branch information
rsc committed Sep 4, 2014
1 parent f403416 commit cb76724
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 18 deletions.
9 changes: 7 additions & 2 deletions misc/cgo/test/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func testCallbackCallers(t *testing.T) {
"runtime.cgocallbackg1",
"runtime.cgocallbackg",
"runtime.cgocallback_gofunc",
"asmcgocall",
"runtime.asmcgocall_errno",
"runtime.cgocall_errno",
"test._Cfunc_callback",
Expand All @@ -182,8 +183,12 @@ func testCallbackCallers(t *testing.T) {
if strings.HasPrefix(fname, "_") {
fname = path.Base(f.Name()[1:])
}
if fname != name[i] {
t.Errorf("expected function name %s, got %s", name[i], fname)
namei := ""
if i < len(name) {
namei = name[i]
}
if fname != namei {
t.Errorf("stk[%d] = %q, want %q", i, fname, namei)
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/pkg/runtime/asm_386.s
Original file line number Diff line number Diff line change
Expand Up @@ -680,17 +680,21 @@ TEXT gosave<>(SB),NOSPLIT,$0
// Call fn(arg) on the scheduler stack,
// aligned appropriately for the gcc ABI.
// See cgocall.c for more details.
TEXT runtime·asmcgocall(SB),NOSPLIT,$12-8
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
MOVL fn+0(FP), AX
MOVL arg+4(FP), BX
MOVL AX, 0(SP)
MOVL BX, 4(SP)
CALL runtime·asmcgocall_errno(SB)
CALL asmcgocall<>(SB)
RET

TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
MOVL fn+0(FP), AX
MOVL arg+4(FP), BX
CALL asmcgocall<>(SB)
MOVL AX, ret+8(FP)
RET

TEXT asmcgocall<>(SB),NOSPLIT,$0-12
// fn in AX, arg in BX
MOVL SP, DX

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

// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Expand Down
13 changes: 8 additions & 5 deletions src/pkg/runtime/asm_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -764,17 +764,21 @@ TEXT gosave<>(SB),NOSPLIT,$0
// Call fn(arg) on the scheduler stack,
// aligned appropriately for the gcc ABI.
// See cgocall.c for more details.
TEXT runtime·asmcgocall(SB),NOSPLIT,$24-16
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
MOVQ fn+0(FP), AX
MOVQ arg+8(FP), BX
MOVQ AX, 0(SP)
MOVQ BX, 8(SP)
CALL runtime·asmcgocall_errno(SB)
CALL asmcgocall<>(SB)
RET

TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-20
MOVQ fn+0(FP), AX
MOVQ arg+8(FP), BX
CALL asmcgocall<>(SB)
MOVL AX, ret+16(FP)
RET

// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.
TEXT asmcgocall<>(SB),NOSPLIT,$0-0
MOVQ SP, DX

// Figure out if we need to switch to m->g0 stack.
Expand Down Expand Up @@ -813,7 +817,6 @@ nosave:
MOVQ 48(SP), DI
MOVQ DI, g(CX)
MOVQ 40(SP), SP
MOVL AX, ret+16(FP)
RET

// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Expand Down
15 changes: 9 additions & 6 deletions src/pkg/runtime/asm_arm.s
Original file line number Diff line number Diff line change
Expand Up @@ -493,17 +493,21 @@ TEXT gosave<>(SB),NOSPLIT,$0
// Call fn(arg) on the scheduler stack,
// aligned appropriately for the gcc ABI.
// See cgocall.c for more details.
TEXT runtime·asmcgocall(SB),NOSPLIT,$12-8
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
MOVW fn+0(FP), R1
MOVW arg+4(FP), R2
MOVW R1, 0(R13)
MOVW R2, 4(R13)
BL runtime·asmcgocall_errno(SB)
MOVW arg+4(FP), R0
BL asmcgocall<>(SB)
RET

TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
MOVW fn+0(FP), R1
MOVW arg+4(FP), R0
BL asmcgocall<>(SB)
MOVW R0, ret+8(FP)
RET

TEXT asmcgocall<>(SB),NOSPLIT,$0-0
// fn in R1, arg in R0.
MOVW R13, R2
MOVW g, R5

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

// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Expand Down

0 comments on commit cb76724

Please sign in to comment.