mirror of
https://github.com/golang/go
synced 2024-11-17 12:04:43 -07:00
runtime: use TOPFRAME to identify top-of-frame functions
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>
This commit is contained in:
parent
fbe74dbf42
commit
54da3ab385
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user