]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use TOPFRAME to identify top-of-frame functions
authorRuss Cox <rsc@golang.org>
Thu, 28 Jan 2021 21:22:52 +0000 (16:22 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 19 Feb 2021 00:02:49 +0000 (00:02 +0000)
No change to actual runtime, but helps reduce the laundry list
of functions.

mcall, morestack, and asmcgocall are not actually top-of-frame,
so those need more attention in follow-up CLs.

mstart moved to assembly so that it can be marked TOPFRAME.

Since TOPFRAME also tells DWARF consumers not to unwind
this way, this change should also improve debuggers a
marginal amount.

This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.
This CL is, however, not windows/arm64-specific.
It is cleanup meant to make the port (and future ports) easier.

Change-Id: If1e0d46ca973de5e46b62948d076f675f285b5d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/288802
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
15 files changed:
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/asm_arm.s
src/runtime/asm_arm64.s
src/runtime/asm_mips64x.s
src/runtime/asm_mipsx.s
src/runtime/asm_ppc64x.s
src/runtime/asm_riscv64.s
src/runtime/asm_s390x.s
src/runtime/asm_wasm.s
src/runtime/proc.go
src/runtime/sys_windows_386.s
src/runtime/sys_windows_amd64.s
src/runtime/sys_windows_arm.s
src/runtime/traceback.go

index fcf74a03cf06c43ee5e8f434a572e363a3111ddd..5b0852f78043eb9c087b8dd2a3185ec10096f427 100644 (file)
@@ -89,7 +89,7 @@ GLOBL _rt0_386_lib_argc<>(SB),NOPTR, $4
 DATA _rt0_386_lib_argv<>(SB)/4, $0
 GLOBL _rt0_386_lib_argv<>(SB),NOPTR, $4
 
-TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
        // Copy arguments forward on an even stack.
        // Users of this function jump to it, they don't call it.
        MOVL    0(SP), AX
@@ -269,6 +269,10 @@ TEXT runtime·asminit(SB),NOSPLIT,$0-0
        FLDCW   runtime·controlWord64(SB)
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       CALL    runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
@@ -1307,7 +1311,7 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0
 
 // The top-most function running on a goroutine
 // returns to goexit+PCQuantum.
-TEXT runtime·goexit(SB),NOSPLIT,$0-0
+TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME,$0-0
        BYTE    $0x90   // NOP
        CALL    runtime·goexit1(SB)    // does not return
        // traceback from goexit1 must hit code range of goexit
index 8ee2ac2123bff5624fd7817ece37fdfddbd20595..a68dc72ae5332a8bf3bf91d84004632b71e52ede 100644 (file)
@@ -84,7 +84,7 @@ GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8
 DATA _rt0_amd64_lib_argv<>(SB)/8, $0
 GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // copy arguments forward on an even stack
        MOVQ    DI, AX          // argc
        MOVQ    SI, BX          // argv
@@ -250,6 +250,10 @@ TEXT runtime·asminit(SB),NOSPLIT,$0-0
        // No per-thread init.
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       CALL    runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
@@ -1440,7 +1444,7 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0
 // so as to make it identifiable to traceback (this
 // function it used as a sentinel; traceback wants to
 // see the func PC, not a wrapper PC).
-TEXT runtime·goexit<ABIInternal>(SB),NOSPLIT,$0-0
+TEXT runtime·goexit<ABIInternal>(SB),NOSPLIT|TOPFRAME,$0-0
        BYTE    $0x90   // NOP
        CALL    runtime·goexit1(SB)    // does not return
        // traceback from goexit1 must hit code range of goexit
index 4620f190744d318844d4dfb929a4a8d70bacd485..f9535bb1bc1198aae4769deecf754ffc8cf3a801 100644 (file)
@@ -112,7 +112,7 @@ GLOBL _rt0_arm_lib_argv<>(SB),NOPTR,$4
 
 // using NOFRAME means do not save LR on stack.
 // argc is in R0, argv is in R1.
-TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
        MOVW    $0xcafebabe, R12
 
        // copy arguments forward on an even stack
@@ -202,6 +202,10 @@ TEXT runtime·asminit(SB),NOSPLIT,$0-0
        WORD    $0xeee1ba10     // vmsr fpscr, r11
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       BL      runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
index 4f0a680fa4c73db504c93c0cb8b947c51b0c2eea..d81759537ecf75fae390d1cc889451199fa6bbc5 100644 (file)
@@ -8,7 +8,7 @@
 #include "funcdata.h"
 #include "textflag.h"
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // SP = stack; R0 = argc; R1 = argv
 
        SUB     $32, RSP
@@ -109,6 +109,10 @@ TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       BL      runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
index f6d8931a15fe485d3e4266f7d980507e98d27919..af27b9b5552f339c73289f9dcf75df6af914c82b 100644 (file)
@@ -11,7 +11,7 @@
 
 #define        REGCTXT R22
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // R29 = stack; R4 = argc; R5 = argv
 
        ADDV    $-24, R29
@@ -85,6 +85,10 @@ TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       JAL     runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
index cf4b1b42cccfd41d97d023c5a8b74e08d5fbad90..0c7d28dcf7da16ba82060aa50e4d99893ad04f2c 100644 (file)
@@ -11,7 +11,7 @@
 
 #define        REGCTXT R22
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // R29 = stack; R4 = argc; R5 = argv
 
        ADDU    $-12, R29
@@ -86,6 +86,10 @@ TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
 TEXT runtime·asminit(SB),NOSPLIT,$0-0
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       JAL     runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
index 90f14d8e54860d0e15906b1703a345428bd51e0a..56e73742ea446fdc69bb3b29067868fdc00f40fe 100644 (file)
@@ -16,7 +16,7 @@
 #define cgoCalleeStackSize 32
 #endif
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer
 
        // initialize essential registers
@@ -124,6 +124,10 @@ TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0
        XOR R0, R0
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       BL      runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
index d06c77b948ea57be79afa4e2a61a6b3d40340012..30f2bd2e4a587438eb19e69dc401ee980e0c9584 100644 (file)
@@ -7,7 +7,7 @@
 #include "textflag.h"
 
 // func rt0_go()
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // X2 = stack; A0 = argc; A1 = argv
        ADD     $-24, X2
        MOV     A0, 8(X2)       // argc
@@ -70,6 +70,10 @@ nocgo:
        WORD $0 // crash if reached
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       CALL    runtime·mstart0(SB)
+       RET // not reached
+
 // void setg_gcc(G*); set g called from gcc with g in A0
 TEXT setg_gcc<>(SB),NOSPLIT,$0-0
        MOV     A0, g
index 203754f32c8c8b02bfab7402a7ba7a2beaa5990e..f9fb1a4c5522c75a672ff20ec26b71362227d090 100644 (file)
@@ -84,7 +84,7 @@ GLOBL _rt0_s390x_lib_argc<>(SB), NOPTR, $8
 DATA _rt0_s90x_lib_argv<>(SB)/8, $0
 GLOBL _rt0_s390x_lib_argv<>(SB), NOPTR, $8
 
-TEXT runtime·rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
        // R2 = argc; R3 = argv; R11 = temp; R13 = g; R15 = stack pointer
        // C TLS base pointer in AR0:AR1
 
@@ -170,6 +170,10 @@ TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
        RET
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       CALL    runtime·mstart0(SB)
+       RET // not reached
+
 /*
  *  go-routine
  */
index 3765c756b37316de5b99748d3c624da25dacea2d..33c335ba5af91bfde9c613cd164b095e03ea090f 100644 (file)
@@ -7,7 +7,7 @@
 #include "funcdata.h"
 #include "textflag.h"
 
-TEXT runtime·rt0_go(SB), NOSPLIT|NOFRAME, $0
+TEXT runtime·rt0_go(SB), NOSPLIT|NOFRAME|TOPFRAME, $0
        // save m->g0 = g0
        MOVD $runtime·g0(SB), runtime·m0+m_g0(SB)
        // save m0 to g0->m
@@ -24,6 +24,10 @@ TEXT runtime·rt0_go(SB), NOSPLIT|NOFRAME, $0
        CALL runtime·mstart(SB) // WebAssembly stack will unwind when switching to another goroutine
        UNDEF
 
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+       CALL    runtime·mstart0(SB)
+       RET // not reached
+
 DATA  runtime·mainPC+0(SB)/8,$runtime·main(SB)
 GLOBL runtime·mainPC(SB),RODATA,$8
 
@@ -424,7 +428,7 @@ CALLFN(·call268435456, 268435456)
 CALLFN(·call536870912, 536870912)
 CALLFN(·call1073741824, 1073741824)
 
-TEXT runtime·goexit(SB), NOSPLIT, $0-0
+TEXT runtime·goexit(SB), NOSPLIT|TOPFRAME, $0-0
        NOP // first PC of goexit is skipped
        CALL runtime·goexit1(SB) // does not return
        UNDEF
index e6670135db43d5ba530f06e64bfc017b775399eb..ccfe0856910ae1efae038da3f19170ac8fdaf0e9 100644 (file)
@@ -1234,7 +1234,10 @@ func mStackIsSystemAllocated() bool {
 }
 
 // mstart is the entry-point for new Ms.
-//
+// It is written in assembly, marked TOPFRAME, and calls mstart0.
+func mstart()
+
+// mstart0 is the Go entry-point for new Ms.
 // This must not split the stack because we may not even have stack
 // bounds set up yet.
 //
@@ -1243,7 +1246,7 @@ func mStackIsSystemAllocated() bool {
 //
 //go:nosplit
 //go:nowritebarrierrec
-func mstart() {
+func mstart0() {
        _g_ := getg()
 
        osStack := _g_.stack.lo == 0
index 576dd28771957b6117a9c5d31f30479fe809435a..4f00c58c16862006411e0b725e16e8f6c8c0a794 100644 (file)
@@ -174,7 +174,7 @@ TEXT runtime·profileloop(SB),NOSPLIT,$0
        ADDL    $12, SP
        JMP     CX
 
-TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
+TEXT runtime·externalthreadhandler(SB),NOSPLIT|TOPFRAME,$0
        PUSHL   BP
        MOVL    SP, BP
        PUSHL   BX
index 6f2abb5444b4f1ffa086891b1f112d2cef45fc7f..aba2811e5978078b7af2ebe27aa8a225bb9571a7 100644 (file)
@@ -215,7 +215,7 @@ TEXT runtime·profileloop(SB),NOSPLIT|NOFRAME,$8
        CALL    runtime·externalthreadhandler(SB)
        RET
 
-TEXT runtime·externalthreadhandler(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·externalthreadhandler(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
        PUSHQ   BP
        MOVQ    SP, BP
        PUSHQ   BX
index 7d134dd3f416cca5bb8fe6c9621fe639600c8ba1..a55f474d39b8550900a0851df1c1be3265745f9c 100644 (file)
@@ -257,7 +257,7 @@ TEXT runtime·profileloop(SB),NOSPLIT|NOFRAME,$0
 // 0 | retval         |
 //   +----------------+
 //
-TEXT runtime·externalthreadhandler(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·externalthreadhandler(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
        MOVM.DB.W [R4-R11, R14], (R13)          // push {r4-r11, lr}
        SUB     $(m__size + g__size + 20), R13  // space for locals
        MOVW    R0, 12(R13)
index 18d8a42854a9b20df7b6c68f215b6a8010acb3ee..e2bd968919207a39b7be0545d73c8faabf52cbc2 100644 (file)
@@ -1002,12 +1002,9 @@ func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
 
 // Does f mark the top of a goroutine stack?
 func topofstack(f funcInfo, g0 bool) bool {
-       return f.funcID == funcID_goexit ||
-               f.funcID == funcID_mstart ||
+       return f.flag&funcFlag_TOPFRAME != 0 ||
                f.funcID == funcID_mcall ||
                f.funcID == funcID_morestack ||
-               f.funcID == funcID_rt0_go ||
-               f.funcID == funcID_externalthreadhandler ||
                // asmcgocall is TOS on the system stack because it
                // switches to the system stack, but in this case we
                // can come back to the regular stack and still want