mirror of
https://github.com/golang/go
synced 2024-11-19 02:04:42 -07:00
runtime: change top-most return PC from goexit to goexit+PCQuantum
If you get a stack of PCs from Callers, it would be expected that every PC is immediately after a call instruction, so to find the line of the call, you look up the line for PC-1. CL 163550043 now explicitly documents that. The most common exception to this is the top-most return PC on the stack, which is the entry address of the runtime.goexit function. Subtracting 1 from that PC will end up in a different function entirely. To remove this special case, make the top-most return PC goexit+PCQuantum and then implement goexit in assembly so that the first instruction can be skipped. Fixes #7690. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/170720043
This commit is contained in:
parent
f9c4c16dce
commit
a5a0733144
@ -2284,3 +2284,9 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0
|
|||||||
MOVL m_curg(AX), AX
|
MOVL m_curg(AX), AX
|
||||||
MOVL (g_stack+stack_hi)(AX), AX
|
MOVL (g_stack+stack_hi)(AX), AX
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// The top-most function running on a goroutine
|
||||||
|
// returns to goexit+PCQuantum.
|
||||||
|
TEXT runtime·goexit(SB),NOSPLIT,$0-0
|
||||||
|
BYTE $0x90 // NOP
|
||||||
|
CALL runtime·goexit1(SB) // does not return
|
||||||
|
@ -2229,3 +2229,9 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0
|
|||||||
MOVQ m_curg(AX), AX
|
MOVQ m_curg(AX), AX
|
||||||
MOVQ (g_stack+stack_hi)(AX), AX
|
MOVQ (g_stack+stack_hi)(AX), AX
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// The top-most function running on a goroutine
|
||||||
|
// returns to goexit+PCQuantum.
|
||||||
|
TEXT runtime·goexit(SB),NOSPLIT,$0-0
|
||||||
|
BYTE $0x90 // NOP
|
||||||
|
CALL runtime·goexit1(SB) // does not return
|
||||||
|
@ -1079,3 +1079,9 @@ TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
|
|||||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// The top-most function running on a goroutine
|
||||||
|
// returns to goexit+PCQuantum.
|
||||||
|
TEXT runtime·goexit(SB),NOSPLIT,$0-0
|
||||||
|
BYTE $0x90 // NOP
|
||||||
|
CALL runtime·goexit1(SB) // does not return
|
||||||
|
@ -1320,3 +1320,9 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$8
|
|||||||
MOVW saveG-8(SP), g
|
MOVW saveG-8(SP), g
|
||||||
MOVW saveR11-4(SP), R11
|
MOVW saveR11-4(SP), R11
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// The top-most function running on a goroutine
|
||||||
|
// returns to goexit+PCQuantum.
|
||||||
|
TEXT runtime·goexit(SB),NOSPLIT,$-4-0
|
||||||
|
MOVW R0, R0 // NOP
|
||||||
|
BL runtime·goexit1(SB) // does not return
|
||||||
|
@ -1643,12 +1643,10 @@ runtime·gosched_m(G *gp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finishes execution of the current goroutine.
|
// Finishes execution of the current goroutine.
|
||||||
// Need to mark it as nosplit, because it runs with sp > stackbase.
|
// Must be NOSPLIT because it is called from Go.
|
||||||
// Since it does not return it does not matter. But if it is preempted
|
|
||||||
// at the split stack check, GC will complain about inconsistent sp.
|
|
||||||
#pragma textflag NOSPLIT
|
#pragma textflag NOSPLIT
|
||||||
void
|
void
|
||||||
runtime·goexit(void)
|
runtime·goexit1(void)
|
||||||
{
|
{
|
||||||
void (*fn)(G*);
|
void (*fn)(G*);
|
||||||
|
|
||||||
@ -2192,7 +2190,7 @@ runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerp
|
|||||||
|
|
||||||
runtime·memclr((byte*)&newg->sched, sizeof newg->sched);
|
runtime·memclr((byte*)&newg->sched, sizeof newg->sched);
|
||||||
newg->sched.sp = (uintptr)sp;
|
newg->sched.sp = (uintptr)sp;
|
||||||
newg->sched.pc = (uintptr)runtime·goexit;
|
newg->sched.pc = (uintptr)runtime·goexit + PCQuantum; // +PCQuantum so that previous instruction is in same function
|
||||||
newg->sched.g = newg;
|
newg->sched.g = newg;
|
||||||
runtime·gostartcallfn(&newg->sched, fn);
|
runtime·gostartcallfn(&newg->sched, fn);
|
||||||
newg->gopc = (uintptr)callerpc;
|
newg->gopc = (uintptr)callerpc;
|
||||||
|
Loading…
Reference in New Issue
Block a user