]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: eliminate uses of BP on amd64
authorAustin Clements <austin@google.com>
Tue, 27 Jan 2015 23:29:02 +0000 (18:29 -0500)
committerAustin Clements <austin@google.com>
Mon, 2 Feb 2015 19:35:56 +0000 (19:35 +0000)
Any place that clobbers BP in the runtime can potentially interfere
with frame pointer unwinding with GOEXPERIMENT=framepointer.  This
change eliminates uses of BP in the runtime to address this problem.
We have spare registers everywhere this occurs, so there's no downside
to eliminating BP.  Where possible, this uses the same new register as
the amd64p32 runtime, which doesn't use BP due to restrictions placed
on it by NaCL.

One nice side effect of this is that it will let perf/VTune unwind the
call stack even through a call to systemstack, which will let us get
really good call graphs from the garbage collector.

Change-Id: I0ffa14cb4dd2b613a7049b8ec59df37c52286212
Reviewed-on: https://go-review.googlesource.com/3390
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/asm_amd64.s
src/runtime/sys_dragonfly_amd64.s
src/runtime/sys_freebsd_amd64.s
src/runtime/sys_linux_amd64.s
src/runtime/sys_netbsd_amd64.s
src/runtime/sys_openbsd_amd64.s

index 8547228ee37804e50ce02bf079661d5b2bce1e83..b1bf4ca9878b8fa2543f9cf33d5bf165736208c8 100644 (file)
@@ -96,8 +96,8 @@ ok:
        CALL    runtime·schedinit(SB)
 
        // create a new goroutine to start program
-       MOVQ    $runtime·main·f(SB), BP               // entry
-       PUSHQ   BP
+       MOVQ    $runtime·main·f(SB), AX               // entry
+       PUSHQ   AX
        PUSHQ   $0                      // arg size
        CALL    runtime·newproc(SB)
        POPQ    AX
@@ -213,8 +213,8 @@ TEXT runtime·systemstack(SB), NOSPLIT, $0-8
        CMPQ    AX, DX
        JEQ     noswitch
 
-       MOVQ    m_curg(BX), BP
-       CMPQ    AX, BP
+       MOVQ    m_curg(BX), R8
+       CMPQ    AX, R8
        JEQ     switch
        
        // Bad: g is not gsignal, not g0, not curg. What is it?
@@ -224,8 +224,8 @@ TEXT runtime·systemstack(SB), NOSPLIT, $0-8
 switch:
        // save our state in g->sched.  Pretend to
        // be systemstack_switch if the G stack is scanned.
-       MOVQ    $runtime·systemstack_switch(SB), BP
-       MOVQ    BP, (g_sched+gobuf_pc)(AX)
+       MOVQ    $runtime·systemstack_switch(SB), SI
+       MOVQ    SI, (g_sched+gobuf_pc)(AX)
        MOVQ    SP, (g_sched+gobuf_sp)(AX)
        MOVQ    AX, (g_sched+gobuf_g)(AX)
 
@@ -305,9 +305,9 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0
        MOVQ    DX, (g_sched+gobuf_ctxt)(SI)
 
        // Call newstack on m->g0's stack.
-       MOVQ    m_g0(BX), BP
-       MOVQ    BP, g(CX)
-       MOVQ    (g_sched+gobuf_sp)(BP), SP
+       MOVQ    m_g0(BX), BX
+       MOVQ    BX, g(CX)
+       MOVQ    (g_sched+gobuf_sp)(BX), SP
        CALL    runtime·newstack(SB)
        MOVQ    $0, 0x1003      // crash if newstack returns
        RET
@@ -619,17 +619,17 @@ TEXT asmcgocall<>(SB),NOSPLIT,$0-0
        // We get called to create new OS threads too, and those
        // come in on the m->g0 stack already.
        get_tls(CX)
-       MOVQ    g(CX), BP
-       MOVQ    g_m(BP), BP
-       MOVQ    m_g0(BP), SI
+       MOVQ    g(CX), R8
+       MOVQ    g_m(R8), R8
+       MOVQ    m_g0(R8), SI
        MOVQ    g(CX), DI
        CMPQ    SI, DI
        JEQ     nosave
-       MOVQ    m_gsignal(BP), SI
+       MOVQ    m_gsignal(R8), SI
        CMPQ    SI, DI
        JEQ     nosave
        
-       MOVQ    m_g0(BP), SI
+       MOVQ    m_g0(R8), SI
        CALL    gosave<>(SB)
        MOVQ    SI, g(CX)
        MOVQ    (g_sched+gobuf_sp)(SI), SP
@@ -683,15 +683,15 @@ TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24
        // the linker analysis by using an indirect call through AX.
        get_tls(CX)
 #ifdef GOOS_windows
-       MOVL    $0, BP
+       MOVL    $0, BX
        CMPQ    CX, $0
        JEQ     2(PC)
 #endif
-       MOVQ    g(CX), BP
-       CMPQ    BP, $0
+       MOVQ    g(CX), BX
+       CMPQ    BX, $0
        JEQ     needm
-       MOVQ    g_m(BP), BP
-       MOVQ    BP, R8 // holds oldm until end of function
+       MOVQ    g_m(BX), BX
+       MOVQ    BX, R8 // holds oldm until end of function
        JMP     havem
 needm:
        MOVQ    $0, 0(SP)
@@ -699,8 +699,8 @@ needm:
        CALL    AX
        MOVQ    0(SP), R8
        get_tls(CX)
-       MOVQ    g(CX), BP
-       MOVQ    g_m(BP), BP
+       MOVQ    g(CX), BX
+       MOVQ    g_m(BX), BX
        
        // Set m->sched.sp = SP, so that if a panic happens
        // during the function we are about to execute, it will
@@ -713,7 +713,7 @@ needm:
        // and then systemstack will try to use it. If we don't set it here,
        // that restored SP will be uninitialized (typically 0) and
        // will not be usable.
-       MOVQ    m_g0(BP), SI
+       MOVQ    m_g0(BX), SI
        MOVQ    SP, (g_sched+gobuf_sp)(SI)
 
 havem:
@@ -722,7 +722,7 @@ havem:
        // Save current sp in m->g0->sched.sp in preparation for
        // switch back to m->curg stack.
        // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
-       MOVQ    m_g0(BP), SI
+       MOVQ    m_g0(BX), SI
        MOVQ    (g_sched+gobuf_sp)(SI), AX
        MOVQ    AX, 0(SP)
        MOVQ    SP, (g_sched+gobuf_sp)(SI)
@@ -742,11 +742,11 @@ havem:
        // the earlier calls.
        //
        // In the new goroutine, 0(SP) holds the saved R8.
-       MOVQ    m_curg(BP), SI
+       MOVQ    m_curg(BX), SI
        MOVQ    SI, g(CX)
        MOVQ    (g_sched+gobuf_sp)(SI), DI  // prepare stack as DI
-       MOVQ    (g_sched+gobuf_pc)(SI), BP
-       MOVQ    BP, -8(DI)
+       MOVQ    (g_sched+gobuf_pc)(SI), BX
+       MOVQ    BX, -8(DI)
        LEAQ    -(8+8)(DI), SP
        MOVQ    R8, 0(SP)
        CALL    runtime·cgocallbackg(SB)
@@ -755,17 +755,17 @@ havem:
        // Restore g->sched (== m->curg->sched) from saved values.
        get_tls(CX)
        MOVQ    g(CX), SI
-       MOVQ    8(SP), BP
-       MOVQ    BP, (g_sched+gobuf_pc)(SI)
+       MOVQ    8(SP), BX
+       MOVQ    BX, (g_sched+gobuf_pc)(SI)
        LEAQ    (8+8)(SP), DI
        MOVQ    DI, (g_sched+gobuf_sp)(SI)
 
        // Switch back to m->g0's stack and restore m->g0->sched.sp.
        // (Unlike m->curg, the g0 goroutine never uses sched.pc,
        // so we do not have to restore it.)
-       MOVQ    g(CX), BP
-       MOVQ    g_m(BP), BP
-       MOVQ    m_g0(BP), SI
+       MOVQ    g(CX), BX
+       MOVQ    g_m(BX), BX
+       MOVQ    m_g0(BX), SI
        MOVQ    SI, g(CX)
        MOVQ    (g_sched+gobuf_sp)(SI), SP
        MOVQ    0(SP), AX
@@ -915,8 +915,8 @@ aes0to15:
        // a page boundary, so we can load it directly.
        MOVOU   -16(AX), X0
        ADDQ    CX, CX
-       MOVQ    $masks<>(SB), BP
-       PAND    (BP)(CX*8), X0
+       MOVQ    $masks<>(SB), AX
+       PAND    (AX)(CX*8), X0
 
        // scramble 3 times
        AESENC  X6, X0
@@ -931,8 +931,8 @@ endofpage:
        // Then shift bytes down using pshufb.
        MOVOU   -32(AX)(CX*1), X0
        ADDQ    CX, CX
-       MOVQ    $shifts<>(SB), BP
-       PSHUFB  (BP)(CX*8), X0
+       MOVQ    $shifts<>(SB), AX
+       PSHUFB  (AX)(CX*8), X0
        AESENC  X6, X0
        AESENC  X7, X0
        AESENC  X7, X0
@@ -1384,13 +1384,13 @@ TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
        CMPQ    SI, DI
        JEQ     allsame
        CMPQ    BX, DX
-       MOVQ    DX, BP
-       CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
-       CMPQ    BP, $8
+       MOVQ    DX, R8
+       CMOVQLT BX, R8 // R8 = min(alen, blen) = # of bytes to compare
+       CMPQ    R8, $8
        JB      small
 
 loop:
-       CMPQ    BP, $16
+       CMPQ    R8, $16
        JBE     _0through16
        MOVOU   (SI), X0
        MOVOU   (DI), X1
@@ -1400,7 +1400,7 @@ loop:
        JNE     diff16  // branch if at least one byte is not equal
        ADDQ    $16, SI
        ADDQ    $16, DI
-       SUBQ    $16, BP
+       SUBQ    $16, R8
        JMP     loop
        
        // AX = bit mask of differences
@@ -1415,15 +1415,15 @@ diff16:
 
        // 0 through 16 bytes left, alen>=8, blen>=8
 _0through16:
-       CMPQ    BP, $8
+       CMPQ    R8, $8
        JBE     _0through8
        MOVQ    (SI), AX
        MOVQ    (DI), CX
        CMPQ    AX, CX
        JNE     diff8
 _0through8:
-       MOVQ    -8(SI)(BP*1), AX
-       MOVQ    -8(DI)(BP*1), CX
+       MOVQ    -8(SI)(R8*1), AX
+       MOVQ    -8(DI)(R8*1), CX
        CMPQ    AX, CX
        JEQ     allsame
 
@@ -1440,7 +1440,7 @@ diff8:
 
        // 0-7 bytes in common
 small:
-       LEAQ    (BP*8), CX      // bytes left -> bits left
+       LEAQ    (R8*8), CX      // bytes left -> bits left
        NEGQ    CX              //  - bits lift (== 64 - bits left mod 64)
        JEQ     allsame
 
@@ -1450,7 +1450,7 @@ small:
        MOVQ    (SI), SI
        JMP     si_finish
 si_high:
-       MOVQ    -8(SI)(BP*1), SI
+       MOVQ    -8(SI)(R8*1), SI
        SHRQ    CX, SI
 si_finish:
        SHLQ    CX, SI
@@ -1461,7 +1461,7 @@ si_finish:
        MOVQ    (DI), DI
        JMP     di_finish
 di_high:
-       MOVQ    -8(DI)(BP*1), DI
+       MOVQ    -8(DI)(R8*1), DI
        SHRQ    CX, DI
 di_finish:
        SHLQ    CX, DI
index db07ed70325d52aed48af49de49546ed902da073..2f2942ae190569225bfb39e42ce15367db52fdef 100644 (file)
@@ -186,9 +186,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVQ    R10, 40(SP)
        
        // g = m->signal
-       MOVQ    g_m(R10), BP
-       MOVQ    m_gsignal(BP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    g_m(R10), AX
+       MOVQ    m_gsignal(AX), AX
+       MOVQ    AX, g(BX)
        
        MOVQ    DI, 0(SP)
        MOVQ    SI, 8(SP)
index 400c1845be68a185a96135f1f706d504ee766668..eac0319d0b13ca12fc063678ad57eb7e861602a1 100644 (file)
@@ -180,9 +180,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVQ    R10, 40(SP)
        
        // g = m->signal
-       MOVQ    g_m(R10), BP
-       MOVQ    m_gsignal(BP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    g_m(R10), AX
+       MOVQ    m_gsignal(AX), AX
+       MOVQ    AX, g(BX)
        
        MOVQ    DI, 0(SP)
        MOVQ    SI, 8(SP)
index 1125edd7fd96271687916f0c0147d997c93875ed..aac741b7131f511665a651a5705087f0765b6860 100644 (file)
@@ -216,9 +216,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVQ    R10, 40(SP)
 
        // g = m->gsignal
-       MOVQ    g_m(R10), BP
-       MOVQ    m_gsignal(BP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    g_m(R10), AX
+       MOVQ    m_gsignal(AX), AX
+       MOVQ    AX, g(BX)
 
        MOVQ    DI, 0(SP)
        MOVQ    SI, 8(SP)
index e26d6066719beb3133c69480ab8de289a3ca8dd5..83de9111dd76f5fd9a3e005063515ef409386c4d 100644 (file)
@@ -236,9 +236,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVQ    R10, 40(SP)
 
        // g = m->signal
-       MOVQ    g_m(R10), BP
-       MOVQ    m_gsignal(BP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    g_m(R10), AX
+       MOVQ    m_gsignal(AX), AX
+       MOVQ    AX, g(BX)
 
        MOVQ    DI, 0(SP)
        MOVQ    SI, 8(SP)
index 9dc0fb6857f15fa566dd0fd7dc5565907bfaa082..f1ee4a9ce1ada4dca224c5b8e37d662a01f8a690 100644 (file)
@@ -227,9 +227,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVQ    R10, 40(SP)
        
        // g = m->signal
-       MOVQ    g_m(R10), BP
-       MOVQ    m_gsignal(BP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    g_m(R10), AX
+       MOVQ    m_gsignal(AX), AX
+       MOVQ    AX, g(BX)
        
        MOVQ    DI, 0(SP)
        MOVQ    SI, 8(SP)