]> Cypherpunks repositories - gostls13.git/commitdiff
32-bit fixes in lessstack.
authorRuss Cox <rsc@golang.org>
Wed, 3 Jun 2009 06:02:12 +0000 (23:02 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 3 Jun 2009 06:02:12 +0000 (23:02 -0700)
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

src/runtime/386/asm.s
src/runtime/amd64/asm.s
src/runtime/proc.c
src/runtime/runtime.h

index b7138105f704081b01eead1da126c35321f6494c..cb6af7a1550f752539484e8f646d178f9f2d7c92 100644 (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
index b69259e314d28a9f406de3ce3fdddfce226d14d0..6fc01bbc98c01ab3ffb01b725efbc773af06c449 100644 (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
index d51a6c013e8792b4dcc39fc4272a5cd4eefb2628..1d065e6d2ad318cd2aa3a0809df4df86a3ce0bd8 100644 (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)
index f2926037aa4e71cbe6164209e707dc090401067a..8b92c446c8219f962ab2a7b0d22e266997be8eab 100644 (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*);