1
0
mirror of https://github.com/golang/go synced 2024-11-19 20:54:39 -07:00

runtime: fix windows build

Implement runtime·write, like on the other systems,
and also runtime·badcallback, in assembly to reduce
stack footprint.

TBR=golang-dev
CC=golang-dev
https://golang.org/cl/5785055
This commit is contained in:
Russ Cox 2012-03-08 15:53:11 -05:00
parent 312ff5b58e
commit 8a1b3d5a57
3 changed files with 94 additions and 45 deletions

View File

@ -38,6 +38,46 @@ TEXT runtime·asmstdcall(SB),7,$0
RET
TEXT runtime·write(SB),7,$24
// write only writes to stderr; ignore fd
MOVL $-12, 0(SP)
MOVL SP, BP
CALL *runtime·GetStdHandle(SB)
MOVL BP, SP
MOVL AX, 0(SP) // handle
MOVL buf+4(FP), DX // pointer
MOVL DX, 4(SP)
MOVL count+8(FP), DX // count
MOVL DX, 8(SP)
LEAL 20(SP), DX // written count
MOVL $0, 0(DX)
MOVL DX, 12(SP)
MOVL $0, 16(SP) // overlapped
CALL *runtime·WriteFile(SB)
MOVL BP, SI
RET
TEXT runtime·badcallback(SB),7,$24
// write only writes to stderr; ignore fd
MOVL $-12, 0(SP)
MOVL SP, BP
CALL *runtime·GetStdHandle(SB)
MOVL BP, SP
MOVL AX, 0(SP) // handle
MOVL $runtime·badcallbackmsg(SB), DX // pointer
MOVL DX, 4(SP)
MOVL runtime·badcallbacklen(SB), DX // count
MOVL DX, 8(SP)
LEAL 20(SP), DX // written count
MOVL $0, 0(DX)
MOVL DX, 12(SP)
MOVL $0, 16(SP) // overlapped
CALL *runtime·WriteFile(SB)
MOVL BP, SI
RET
// faster get/set last error
TEXT runtime·getlasterror(SB),7,$0
MOVL 0x34(FS), AX

View File

@ -60,6 +60,49 @@ loadregs:
RET
TEXT runtime·write(SB),7,$48
// write only ever writes to stderr; ignore fd
MOVQ $-12, CX // stderr
MOVQ CX, 0(SP)
MOVQ runtime·GetStdHandle(SB), AX
CALL AX
MOVQ AX, CX // handle
MOVQ CX, 0(SP)
MOVQ buf+8(FP), DX // pointer
MOVQ DX, 8(SP)
MOVL count+16(FP), R8 // count
MOVQ R8, 16(SP)
LEAQ 40(SP), R9 // written count
MOVQ $0, 0(R9)
MOVQ R9, 24(SP)
MOVQ $0, 32(SP) // overlapped
MOVQ runtime·WriteFile(SB), AX
CALL AX
RET
TEXT runtime·badcallback(SB),7,$48
MOVQ $-12, CX // stderr
MOVQ CX, 0(SP)
MOVQ runtime·GetStdHandle(SB), AX
CALL AX
MOVQ AX, CX // handle
MOVQ CX, 0(SP)
MOVQ $runtime·badcallbackmsg(SB), DX // pointer
MOVQ DX, 8(SP)
MOVL $runtime·badcallbacklen(SB), R8 // count
MOVQ R8, 16(SP)
LEAQ 40(SP), R9 // written count
MOVQ $0, 0(R9)
MOVQ R9, 24(SP)
MOVQ $0, 32(SP) // overlapped
MOVQ runtime·WriteFile(SB), AX
CALL AX
RET
// faster get/set last error
TEXT runtime·getlasterror(SB),7,$0
MOVQ 0x30(GS), AX
@ -207,15 +250,18 @@ TEXT runtime·callbackasm(SB),7,$0
MOVQ R14, 8(SP)
MOVQ R15, 0(SP)
// prepare call stack. use SUBQ to hide from stack frame checks
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
PUSHQ DX // uintptr framesize
PUSHQ CX // void *frame
PUSHQ AX // void (*fn)(void*)
SUBQ $24, SP
MOVQ DX, 16(SP) // uintptr framesize
MOVQ CX, 8(SP) // void *frame
MOVQ AX, 0(SP) // void (*fn)(void*)
CLD
CALL runtime·cgocallback(SB)
POPQ AX
POPQ CX
POPQ DX
MOVQ 0(SP), AX
MOVQ 8(SP), CX
MOVQ 16(SP), DX
ADDQ $24, SP
// restore registers as required for windows callback
// 6l does not allow writing many POPs here issuing a warning "nosplit stack overflow"

View File

@ -114,27 +114,6 @@ runtime·exit(int32 code)
runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
}
int32
runtime·write(int32 fd, void *buf, int32 n)
{
void *handle;
uint32 written;
written = 0;
switch(fd) {
case 1:
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11);
break;
case 2:
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12);
break;
default:
return -1;
}
runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0);
return written;
}
void
runtime·osyield(void)
{
@ -423,21 +402,5 @@ runtime·setprof(bool on)
USED(on);
}
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
// This runs on a foreign stack, without an m or a g. No stack split.
#pragma textflag 7
void
runtime·badcallback(void)
{
uint32 written;
runtime·stdcall(
runtime·WriteFile, 5,
runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12), // stderr
badcallback,
(uintptr)(sizeof badcallback - 1),
&written,
nil
);
}
int8 runtime·badcallbackmsg[] = "runtime: cgo callback on thread not created by Go.\n";
int32 runtime·badcallbacklen = sizeof runtime·badcallbackmsg - 1;