1
0
mirror of https://github.com/golang/go synced 2024-11-13 19:00:25 -07:00

segmented stacks

SVN=125267
This commit is contained in:
Ken Thompson 2008-06-29 20:40:08 -07:00
parent d3237f9a2a
commit b987f7a757
6 changed files with 311 additions and 64 deletions

View File

@ -346,8 +346,7 @@ EXTERN char* EXPTAB;
EXTERN Prog undefp; EXTERN Prog undefp;
EXTERN ulong stroffset; EXTERN ulong stroffset;
EXTERN vlong textstksiz; EXTERN vlong textstksiz;
EXTERN vlong textinarg; EXTERN vlong textarg;
EXTERN vlong textoutarg;
#define UP (&undefp) #define UP (&undefp)

View File

@ -106,11 +106,11 @@ Dconv(Fmt *fp)
goto brk; goto brk;
} }
parsetextconst(a->offset); parsetextconst(a->offset);
if(textinarg == 0 && textoutarg == 0) { if(textarg == 0) {
sprint(str, "$%lld", textstksiz); sprint(str, "$%lld", textstksiz);
goto brk; goto brk;
} }
sprint(str, "$%lld-%lld-%lld", textstksiz, textinarg, textoutarg); sprint(str, "$%lld-%lld", textstksiz, textarg);
goto brk; goto brk;
} }
@ -422,18 +422,15 @@ parsetextconst(vlong arg)
if(textstksiz & 0x80000000LL) if(textstksiz & 0x80000000LL)
textstksiz = -(-textstksiz & 0xffffffffLL); textstksiz = -(-textstksiz & 0xffffffffLL);
textarg = (arg >> 32) & 0xffffffffLL;
// the following throws away one bit if(textarg & 0x80000000LL)
// of precision, but maintains compat textarg = 0;
textinarg = (arg >> 32) & 0xffffLL; if(textarg <= 0)
if(textinarg & 0x8000LL) textarg = 100;
textinarg = -(-textinarg & 0xffffLL); if(textarg > textstksiz) {
if(textinarg <= 0) textarg = textstksiz;
textinarg = 100; if(textarg <= 0)
textarg = 0;
textoutarg = (arg >> 48) & 0xffffLL; }
if(textoutarg & 0x8000LL) textarg = (textarg+7) & ~7LL;
textoutarg = -(-textoutarg & 0xffffLL);
if(textoutarg <= 0)
textoutarg = 0;
} }

View File

@ -668,7 +668,7 @@ dostkoff(void)
q = P; q = P;
if(pmorestack != P) if(pmorestack != P)
if(!(p->from.scale & NOSPLIT)) { if(!(p->from.scale & NOSPLIT)) {
if(autoffset <= 50) { if(autoffset <= 75) {
// small stack // small stack
p = appendp(p); p = appendp(p);
p->as = ACMPQ; p->as = ACMPQ;
@ -678,14 +678,9 @@ dostkoff(void)
} else { } else {
// large stack // large stack
p = appendp(p); p = appendp(p);
p->as = AMOVQ; p->as = ALEAQ;
p->from.type = D_SP; p->from.type = D_INDIR+D_SP;
p->to.type = D_AX; p->from.offset = -(autoffset-75);
p = appendp(p);
p->as = ASUBQ;
p->from.type = D_CONST;
p->from.offset = autoffset-50;
p->to.type = D_AX; p->to.type = D_AX;
p = appendp(p); p = appendp(p);
@ -693,6 +688,7 @@ dostkoff(void)
p->from.type = D_AX; p->from.type = D_AX;
p->to.type = D_INDIR+D_R15; p->to.type = D_INDIR+D_R15;
} }
// common // common
p = appendp(p); p = appendp(p);
p->as = AJHI; p->as = AJHI;
@ -703,9 +699,14 @@ dostkoff(void)
p = appendp(p); p = appendp(p);
p->as = AMOVQ; p->as = AMOVQ;
p->from.type = D_CONST; p->from.type = D_CONST;
p->from.offset = curtext->to.offset; p->from.offset = 0;
p->to.type = D_AX; p->to.type = D_AX;
/* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
if(autoffset+160 > 4096)
p->from.offset = (autoffset+160) & ~7LL;
p->from.offset |= textarg<<32;
p = appendp(p); p = appendp(p);
p->as = ACALL; p->as = ACALL;
p->to.type = D_BRANCH; p->to.type = D_BRANCH;

View File

@ -5,30 +5,40 @@
TEXT _rt0_amd64_darwin(SB),7,$-8 TEXT _rt0_amd64_darwin(SB),7,$-8
// copy arguments forward on an even stack // copy arguments forward on an even stack
MOVQ 0(SP), AX // argc MOVQ 0(SP), AX // argc
LEAQ 8(SP), BX // argv LEAQ 8(SP), BX // argv
SUBQ $(4*8+7), SP // 2args 2auto
ANDQ $~7, SP ANDQ $~7, SP
SUBQ $32, SP
MOVQ AX, 16(SP) MOVQ AX, 16(SP)
MOVQ BX, 24(SP) MOVQ BX, 24(SP)
// allocate the per-user block // allocate the per-user block
LEAQ peruser<>(SB), R15 // dedicated u. register LEAQ peruser<>(SB), R15 // dedicated u. register
MOVQ SP, AX
SUBQ $4096, AX LEAQ (-4096+104+4*8)(SP), AX
MOVQ AX, 0(R15) MOVQ AX, 0(R15) // 0(R15) is stack limit (w 104b guard)
MOVL $1024, AX
MOVL AX, 0(SP)
CALL mal(SB)
LEAQ 104(AX), BX
MOVQ BX, 16(R15) // 16(R15) is limit of istack (w 104b guard)
ADDQ 0(SP), AX
LEAQ (-4*8)(AX), BX
MOVQ BX, 24(R15) // 24(R15) is base of istack (w auto*4)
CALL check(SB) CALL check(SB)
// process the arguments // process the arguments
MOVL 16(SP), AX MOVL 16(SP), AX // copy argc
MOVL AX, 0(SP) MOVL AX, 0(SP)
MOVQ 24(SP), AX MOVQ 24(SP), AX // copy argv
MOVQ AX, 8(SP) MOVQ AX, 8(SP)
CALL args(SB) CALL args(SB)
@ -38,15 +48,131 @@ TEXT _rt0_amd64_darwin(SB),7,$-8
MOVQ AX, 0(SP) // exit status MOVQ AX, 0(SP) // exit status
CALL sys·exit(SB) CALL sys·exit(SB)
CALL notok(SB) CALL notok(SB) // fault
ADDQ $32, SP
RET RET
//
// the calling sequence for a routine that
// needs N bytes stack, A args.
//
// N1 = (N+160 > 4096)? N+160: 0
// A1 = A
//
// if N <= 75
// CMPQ SP, 0(R15)
// JHI 3(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// CALL _morestack
//
// if N > 75
// LEAQ (-N-75)(SP), AX
// CMPQ AX, 0(R15)
// JHI 3(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// CALL _morestack
//
TEXT _morestack(SB), 7, $0 TEXT _morestack(SB), 7, $0
MOVQ SP, AX // save stuff on interrupt stack
SUBQ $1024, AX
MOVQ 24(R15), BX // istack
MOVQ SP, 8(BX) // old SP
MOVQ AX, 16(BX) // magic number
MOVQ 0(R15), AX // old limit
MOVQ AX, 24(BX)
// switch and set up new limit
MOVQ BX, SP
MOVQ 16(R15), AX // istack limit
MOVQ AX, 0(R15) MOVQ AX, 0(R15)
// allocate a new stack max of request and 4k
MOVL 16(SP), AX // magic number
CMPL AX, $4096
JHI 2(PC)
MOVL $4096, AX
MOVL AX, 0(SP)
CALL mal(SB)
// switch to new stack
MOVQ SP, BX // istack
ADDQ $104, AX // new stack limit
MOVQ AX, 0(R15)
ADDQ 0(SP), AX
LEAQ (-104-4*8)(AX), SP // new SP
MOVQ 8(R15), AX
MOVQ AX, 0(SP) // old base
MOVQ SP, 8(R15) // new base
// copy needed stuff from istack to new stack
MOVQ 16(BX), AX // magic number
MOVQ AX, 16(SP)
MOVQ 24(BX), AX // old limit
MOVQ AX, 24(SP)
MOVQ 8(BX), AX // old SP
MOVQ AX, 8(SP)
// are there parameters
MOVL 20(SP), CX // copy count
CMPL CX, $0
JEQ easy
// copy in
LEAQ 16(AX), SI
SUBQ CX, SP
MOVQ SP, DI
SHRL $3, CX
CLD
REP
MOVSQ
// call the intended
CALL 0(AX)
// copy out
MOVQ SP, SI
MOVQ 8(R15), BX // new base
MOVQ 8(BX), AX // old SP
LEAQ 16(AX), DI
MOVL 20(BX), CX // copy count
SHRL $3, CX
CLD
REP
MOVSQ
// restore old SP and limit
MOVQ 8(R15), SP // new base
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 0(SP), AX
MOVQ AX, 8(R15) // old base
MOVQ 8(SP), AX // old SP
MOVQ AX, SP
// and return to the call behind mine
ADDQ $8, SP
RET
easy:
CALL 0(AX)
// restore old SP and limit
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 0(SP), AX
MOVQ AX, 8(R15) // old base
MOVQ 8(SP), AX // old SP
MOVQ AX, SP
// and return to the call behind mine
ADDQ $8, SP
RET RET
TEXT FLUSH(SB),7,$-8 TEXT FLUSH(SB),7,$-8

View File

@ -5,30 +5,40 @@
TEXT _rt0_amd64_linux(SB),7,$-8 TEXT _rt0_amd64_linux(SB),7,$-8
// copy arguments forward on an even stack // copy arguments forward on an even stack
MOVQ 0(SP), AX // argc MOVQ 0(SP), AX // argc
LEAQ 8(SP), BX // argv LEAQ 8(SP), BX // argv
SUBQ $(4*8+7), SP // 2args 2auto
ANDQ $~7, SP ANDQ $~7, SP
SUBQ $32, SP
MOVQ AX, 16(SP) MOVQ AX, 16(SP)
MOVQ BX, 24(SP) MOVQ BX, 24(SP)
// allocate the per-user block // allocate the per-user block
LEAQ peruser<>(SB), R15 // dedicated u. register LEAQ peruser<>(SB), R15 // dedicated u. register
MOVQ SP, AX
SUBQ $4096, AX LEAQ (-4096+104+4*8)(SP), AX
MOVQ AX, 0(R15) MOVQ AX, 0(R15) // 0(R15) is stack limit (w 104b guard)
MOVL $1024, AX
MOVL AX, 0(SP)
CALL mal(SB)
LEAQ 104(AX), BX
MOVQ BX, 16(R15) // 16(R15) is limit of istack (w 104b guard)
ADDQ 0(SP), AX
LEAQ (-4*8)(AX), BX
MOVQ BX, 24(R15) // 24(R15) is base of istack (w auto*4)
CALL check(SB) CALL check(SB)
// process the arguments // process the arguments
MOVL 16(SP), AX MOVL 16(SP), AX // copy argc
MOVL AX, 0(SP) MOVL AX, 0(SP)
MOVQ 24(SP), AX MOVQ 24(SP), AX // copy argv
MOVQ AX, 8(SP) MOVQ AX, 8(SP)
CALL args(SB) CALL args(SB)
@ -38,15 +48,131 @@ TEXT _rt0_amd64_linux(SB),7,$-8
MOVQ AX, 0(SP) // exit status MOVQ AX, 0(SP) // exit status
CALL sys·exit(SB) CALL sys·exit(SB)
CALL notok(SB) CALL notok(SB) // fault
ADDQ $32, SP
RET RET
//
// the calling sequence for a routine that
// needs N bytes stack, A args.
//
// N1 = (N+160 > 4096)? N+160: 0
// A1 = A
//
// if N <= 75
// CMPQ SP, 0(R15)
// JHI 3(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// CALL _morestack
//
// if N > 75
// LEAQ (-N-75)(SP), AX
// CMPQ AX, 0(R15)
// JHI 3(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// CALL _morestack
//
TEXT _morestack(SB), 7, $0 TEXT _morestack(SB), 7, $0
MOVQ SP, AX // save stuff on interrupt stack
SUBQ $1024, AX
MOVQ 24(R15), BX // istack
MOVQ SP, 8(BX) // old SP
MOVQ AX, 16(BX) // magic number
MOVQ 0(R15), AX // old limit
MOVQ AX, 24(BX)
// switch and set up new limit
MOVQ BX, SP
MOVQ 16(R15), AX // istack limit
MOVQ AX, 0(R15) MOVQ AX, 0(R15)
// allocate a new stack max of request and 4k
MOVL 16(SP), AX // magic number
CMPL AX, $4096
JHI 2(PC)
MOVL $4096, AX
MOVL AX, 0(SP)
CALL mal(SB)
// switch to new stack
MOVQ SP, BX // istack
ADDQ $104, AX // new stack limit
MOVQ AX, 0(R15)
ADDQ 0(SP), AX
LEAQ (-104-4*8)(AX), SP // new SP
MOVQ 8(R15), AX
MOVQ AX, 0(SP) // old base
MOVQ SP, 8(R15) // new base
// copy needed stuff from istack to new stack
MOVQ 16(BX), AX // magic number
MOVQ AX, 16(SP)
MOVQ 24(BX), AX // old limit
MOVQ AX, 24(SP)
MOVQ 8(BX), AX // old SP
MOVQ AX, 8(SP)
// are there parameters
MOVL 20(SP), CX // copy count
CMPL CX, $0
JEQ easy
// copy in
LEAQ 16(AX), SI
SUBQ CX, SP
MOVQ SP, DI
SHRL $3, CX
CLD
REP
MOVSQ
// call the intended
CALL 0(AX)
// copy out
MOVQ SP, SI
MOVQ 8(R15), BX // new base
MOVQ 8(BX), AX // old SP
LEAQ 16(AX), DI
MOVL 20(BX), CX // copy count
SHRL $3, CX
CLD
REP
MOVSQ
// restore old SP and limit
MOVQ 8(R15), SP // new base
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 0(SP), AX
MOVQ AX, 8(R15) // old base
MOVQ 8(SP), AX // old SP
MOVQ AX, SP
// and return to the call behind mine
ADDQ $8, SP
RET
easy:
CALL 0(AX)
// restore old SP and limit
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 0(SP), AX
MOVQ AX, 8(R15) // old base
MOVQ 8(SP), AX // old SP
MOVQ AX, SP
// and return to the call behind mine
ADDQ $8, SP
RET RET
TEXT FLUSH(SB),7,$-8 TEXT FLUSH(SB),7,$-8
@ -145,7 +271,7 @@ TEXT notok(SB),1,$-8
TEXT sys·memclr(SB),1,$-8 TEXT sys·memclr(SB),1,$-8
MOVQ 8(SP), DI // arg 1 addr MOVQ 8(SP), DI // arg 1 addr
MOVL 16(SP), CX // arg 2 count MOVL 16(SP), CX // arg 2 count (cannot be zero)
ADDL $7, CX ADDL $7, CX
SHRL $3, CX SHRL $3, CX
MOVQ $0, AX MOVQ $0, AX

View File

@ -183,7 +183,7 @@ brk(uint32 n)
{ {
byte* v; byte* v;
v = sys·mmap(nil, NHUNK, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); v = sys·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
sys·memclr(v, n); sys·memclr(v, n);
nmmap += n; nmmap += n;
return v; return v;
@ -194,10 +194,8 @@ mal(uint32 n)
{ {
byte* v; byte* v;
// round to keep everything 64-bit alligned // round to keep everything 64-bit aligned
while(n & 7) n = (n+7) & ~7;
n++;
nmal += n; nmal += n;
// do we have enough in contiguous hunk // do we have enough in contiguous hunk