1
0
mirror of https://github.com/golang/go synced 2024-11-26 07:47:57 -07:00

32-bit fixes in lessstack.

avoid tight coupling between deferreturn and jmpdefer.
before, jmpdefer knew the exact frame size of deferreturn
in order to pop it off the stack.  now, deferreturn passes
jmpdefer a pointer to the frame above it explicitly.
that avoids a magic constant and should be less fragile.

R=r
DELTA=32  (6 added, 3 deleted, 23 changed)
OCL=29801
CL=29804
This commit is contained in:
Russ Cox 2009-06-02 23:02:12 -07:00
parent 07393f8706
commit aa3222d88f
4 changed files with 28 additions and 25 deletions

View File

@ -157,15 +157,17 @@ TEXT cas(SB), 7, $0
MOVL $1, AX
RET
// void jmpdefer(byte*);
// void jmpdefer(fn, sp);
// called from deferreturn.
// 1. pop the caller
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
TEXT jmpdefer(SB), 7, $0
MOVL 4(SP), AX // function
ADDL $(4+56), SP // pop saved PC and callers frame
SUBL $5, (SP) // reposition his return address
JMP AX // and goto function
MOVL 4(SP), AX // fn
MOVL 8(SP), BX // caller sp
LEAL -4(BX), SP // caller sp after CALL
SUBL $5, (SP) // return to CALL again
JMP AX // but first run the deferred function
TEXT sys·memclr(SB),7,$0
MOVL 4(SP), DI // arg 1 addr

View File

@ -172,7 +172,7 @@ TEXT setspgoto(SB), 7, $0
MOVQ AX, SP
PUSHQ CX
JMP BX
POPQ AX
POPQ AX // not reached
RET
// bool cas(int32 *val, int32 old, int32 new)
@ -194,12 +194,14 @@ TEXT cas(SB), 7, $0
MOVL $1, AX
RET
// void jmpdefer(byte*);
// void jmpdefer(fn, sp);
// called from deferreturn.
// 1. pop the caller
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
TEXT jmpdefer(SB), 7, $0
MOVQ 8(SP), AX // function
ADDQ $(8+56), SP // pop saved PC and callers frame
SUBQ $5, (SP) // reposition his return address
JMP AX // and goto function
MOVQ 8(SP), AX // fn
MOVQ 16(SP), BX // caller sp
LEAQ -8(BX), SP // caller sp after CALL
SUBQ $5, (SP) // return to CALL again
JMP AX // but first run the deferred function

View File

@ -607,7 +607,7 @@ oldstack(void)
Stktop *top;
uint32 args;
byte *sp;
uint64 oldsp, oldpc, oldbase, oldguard;
uintptr oldsp, oldpc, oldbase, oldguard;
// printf("oldstack m->cret=%p\n", m->cret);
@ -622,10 +622,10 @@ oldstack(void)
mcpy(top->oldsp+2*sizeof(uintptr), sp, args);
}
oldsp = (uint64)top->oldsp + 8;
oldpc = *(uint64*)(top->oldsp + 8);
oldbase = (uint64)top->oldbase;
oldguard = (uint64)top->oldguard;
oldsp = (uintptr)top->oldsp + sizeof(uintptr);
oldpc = *(uintptr*)oldsp;
oldbase = (uintptr)top->oldbase;
oldguard = (uintptr)top->oldguard;
stackfree((byte*)m->curg->stackguard - StackGuard);
@ -645,6 +645,7 @@ oldstack(void)
gogoret(&m->morestack, m->cret);
}
#pragma textflag 7
void
lessstack(void)
{
@ -818,13 +819,11 @@ sys·deferproc(int32 siz, byte* fn, byte* arg0)
#pragma textflag 7
void
sys·deferreturn(int32 arg0)
sys·deferreturn(uintptr arg0)
{
// warning: jmpdefer knows the frame size
// of this routine. dont change anything
// that might change the frame size
Defer *d;
byte *sp;
byte *sp, *fn;
uintptr *caller;
d = g->defer;
if(d == nil)
@ -834,10 +833,10 @@ sys·deferreturn(int32 arg0)
return;
mcpy(d->sp, d->args, d->siz);
g->defer = d->link;
sp = d->fn;
fn = d->fn;
free(d);
jmpdefer(sp);
}
jmpdefer(fn, sp);
}
void
runtime·Breakpoint(void)

View File

@ -314,7 +314,7 @@ int32 write(int32, void*, int32);
void close(int32);
int32 fstat(int32, void*);
bool cas(uint32*, uint32, uint32);
void jmpdefer(byte*);
void jmpdefer(byte*, void*);
void exit1(int32);
void ready(G*);
byte* getenv(int8*);