Commit aa3222d8 authored by Russ Cox's avatar Russ Cox

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
parent 07393f87
......@@ -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
......
......@@ -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
......@@ -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)
......
......@@ -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*);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment