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:
parent
07393f8706
commit
aa3222d88f
@ -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*);
|
||||
|
Loading…
Reference in New Issue
Block a user