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 ...@@ -157,15 +157,17 @@ TEXT cas(SB), 7, $0
MOVL $1, AX MOVL $1, AX
RET RET
// void jmpdefer(byte*); // void jmpdefer(fn, sp);
// called from deferreturn.
// 1. pop the caller // 1. pop the caller
// 2. sub 5 bytes from the callers return // 2. sub 5 bytes from the callers return
// 3. jmp to the argument // 3. jmp to the argument
TEXT jmpdefer(SB), 7, $0 TEXT jmpdefer(SB), 7, $0
MOVL 4(SP), AX // function MOVL 4(SP), AX // fn
ADDL $(4+56), SP // pop saved PC and callers frame MOVL 8(SP), BX // caller sp
SUBL $5, (SP) // reposition his return address LEAL -4(BX), SP // caller sp after CALL
JMP AX // and goto function SUBL $5, (SP) // return to CALL again
JMP AX // but first run the deferred function
TEXT sys·memclr(SB),7,$0 TEXT sys·memclr(SB),7,$0
MOVL 4(SP), DI // arg 1 addr MOVL 4(SP), DI // arg 1 addr
......
...@@ -172,7 +172,7 @@ TEXT setspgoto(SB), 7, $0 ...@@ -172,7 +172,7 @@ TEXT setspgoto(SB), 7, $0
MOVQ AX, SP MOVQ AX, SP
PUSHQ CX PUSHQ CX
JMP BX JMP BX
POPQ AX POPQ AX // not reached
RET RET
// bool cas(int32 *val, int32 old, int32 new) // bool cas(int32 *val, int32 old, int32 new)
...@@ -194,12 +194,14 @@ TEXT cas(SB), 7, $0 ...@@ -194,12 +194,14 @@ TEXT cas(SB), 7, $0
MOVL $1, AX MOVL $1, AX
RET RET
// void jmpdefer(byte*); // void jmpdefer(fn, sp);
// called from deferreturn.
// 1. pop the caller // 1. pop the caller
// 2. sub 5 bytes from the callers return // 2. sub 5 bytes from the callers return
// 3. jmp to the argument // 3. jmp to the argument
TEXT jmpdefer(SB), 7, $0 TEXT jmpdefer(SB), 7, $0
MOVQ 8(SP), AX // function MOVQ 8(SP), AX // fn
ADDQ $(8+56), SP // pop saved PC and callers frame MOVQ 16(SP), BX // caller sp
SUBQ $5, (SP) // reposition his return address LEAQ -8(BX), SP // caller sp after CALL
JMP AX // and goto function SUBQ $5, (SP) // return to CALL again
JMP AX // but first run the deferred function
...@@ -607,7 +607,7 @@ oldstack(void) ...@@ -607,7 +607,7 @@ oldstack(void)
Stktop *top; Stktop *top;
uint32 args; uint32 args;
byte *sp; byte *sp;
uint64 oldsp, oldpc, oldbase, oldguard; uintptr oldsp, oldpc, oldbase, oldguard;
// printf("oldstack m->cret=%p\n", m->cret); // printf("oldstack m->cret=%p\n", m->cret);
...@@ -622,10 +622,10 @@ oldstack(void) ...@@ -622,10 +622,10 @@ oldstack(void)
mcpy(top->oldsp+2*sizeof(uintptr), sp, args); mcpy(top->oldsp+2*sizeof(uintptr), sp, args);
} }
oldsp = (uint64)top->oldsp + 8; oldsp = (uintptr)top->oldsp + sizeof(uintptr);
oldpc = *(uint64*)(top->oldsp + 8); oldpc = *(uintptr*)oldsp;
oldbase = (uint64)top->oldbase; oldbase = (uintptr)top->oldbase;
oldguard = (uint64)top->oldguard; oldguard = (uintptr)top->oldguard;
stackfree((byte*)m->curg->stackguard - StackGuard); stackfree((byte*)m->curg->stackguard - StackGuard);
...@@ -645,6 +645,7 @@ oldstack(void) ...@@ -645,6 +645,7 @@ oldstack(void)
gogoret(&m->morestack, m->cret); gogoret(&m->morestack, m->cret);
} }
#pragma textflag 7
void void
lessstack(void) lessstack(void)
{ {
...@@ -818,13 +819,11 @@ sys·deferproc(int32 siz, byte* fn, byte* arg0) ...@@ -818,13 +819,11 @@ sys·deferproc(int32 siz, byte* fn, byte* arg0)
#pragma textflag 7 #pragma textflag 7
void 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; Defer *d;
byte *sp; byte *sp, *fn;
uintptr *caller;
d = g->defer; d = g->defer;
if(d == nil) if(d == nil)
...@@ -834,10 +833,10 @@ sys·deferreturn(int32 arg0) ...@@ -834,10 +833,10 @@ sys·deferreturn(int32 arg0)
return; return;
mcpy(d->sp, d->args, d->siz); mcpy(d->sp, d->args, d->siz);
g->defer = d->link; g->defer = d->link;
sp = d->fn; fn = d->fn;
free(d); free(d);
jmpdefer(sp); jmpdefer(fn, sp);
} }
void void
runtime·Breakpoint(void) runtime·Breakpoint(void)
......
...@@ -314,7 +314,7 @@ int32 write(int32, void*, int32); ...@@ -314,7 +314,7 @@ int32 write(int32, void*, int32);
void close(int32); void close(int32);
int32 fstat(int32, void*); int32 fstat(int32, void*);
bool cas(uint32*, uint32, uint32); bool cas(uint32*, uint32, uint32);
void jmpdefer(byte*); void jmpdefer(byte*, void*);
void exit1(int32); void exit1(int32);
void ready(G*); void ready(G*);
byte* getenv(int8*); 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