Skip to content

Commit 361d51a

Browse files
fengyoulinrandall77
authored andcommitted
runtime: remove the pc field of _defer struct
Since we always can get the address of `CALL runtime.deferreturn(SB)` from the unwinder, so it is not necessary to record the caller's pc in the _defer struct. For the stack allocated _defer, this CL makes the frame smaller. Change-Id: I0fd347e4bc07cf8a9b954816323df30fc52552b6 Reviewed-on: https://go-review.googlesource.com/c/go/+/716720 Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
1 parent 00ee186 commit 361d51a

File tree

4 files changed

+9
-21
lines changed

4 files changed

+9
-21
lines changed

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7797,7 +7797,7 @@ func callTargetLSym(callee *ir.Name) *obj.LSym {
77977797
}
77987798

77997799
// deferStructFnField is the field index of _defer.fn.
7800-
const deferStructFnField = 4
7800+
const deferStructFnField = 3
78017801

78027802
var deferType *types.Type
78037803

@@ -7817,7 +7817,6 @@ func deferstruct() *types.Type {
78177817
makefield("heap", types.Types[types.TBOOL]),
78187818
makefield("rangefunc", types.Types[types.TBOOL]),
78197819
makefield("sp", types.Types[types.TUINTPTR]),
7820-
makefield("pc", types.Types[types.TUINTPTR]),
78217820
// Note: the types here don't really matter. Defer structures
78227821
// are always scanned explicitly during stack copying and GC,
78237822
// so we make them uintptr type even though they are real pointers.

src/runtime/heapdump.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,6 @@ func dumpgoroutine(gp *g) {
382382
dumpint(uint64(uintptr(unsafe.Pointer(d))))
383383
dumpint(uint64(uintptr(unsafe.Pointer(gp))))
384384
dumpint(uint64(d.sp))
385-
dumpint(uint64(d.pc))
386385
fn := *(**funcval)(unsafe.Pointer(&d.fn))
387386
dumpint(uint64(uintptr(unsafe.Pointer(fn))))
388387
if d.fn == nil {

src/runtime/panic.go

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,6 @@ func deferproc(fn func()) {
354354
d.link = gp._defer
355355
gp._defer = d
356356
d.fn = fn
357-
d.pc = sys.GetCallerPC()
358357
// We must not be preempted between calling GetCallerSP and
359358
// storing it to d.sp because GetCallerSP's result is a
360359
// uintptr stack pointer.
@@ -458,7 +457,6 @@ func deferrangefunc() any {
458457
d := newdefer()
459458
d.link = gp._defer
460459
gp._defer = d
461-
d.pc = sys.GetCallerPC()
462460
// We must not be preempted between calling GetCallerSP and
463461
// storing it to d.sp because GetCallerSP's result is a
464462
// uintptr stack pointer.
@@ -518,7 +516,6 @@ func deferconvert(d0 *_defer) {
518516
}
519517
for d1 := d; ; d1 = d1.link {
520518
d1.sp = d0.sp
521-
d1.pc = d0.pc
522519
if d1.link == nil {
523520
d1.link = tail
524521
break
@@ -547,7 +544,6 @@ func deferprocStack(d *_defer) {
547544
d.heap = false
548545
d.rangefunc = false
549546
d.sp = sys.GetCallerSP()
550-
d.pc = sys.GetCallerPC()
551547
// The lines below implement:
552548
// d.panic = nil
553549
// d.fd = nil
@@ -977,8 +973,6 @@ func (p *_panic) nextDefer() (func(), bool) {
977973

978974
fn := d.fn
979975

980-
p.retpc = d.pc
981-
982976
// Unlink and free.
983977
popDefer(gp)
984978

@@ -1018,6 +1012,12 @@ func (p *_panic) nextFrame() (ok bool) {
10181012
// it's non-zero.
10191013

10201014
if u.frame.sp == limit {
1015+
f := u.frame.fn
1016+
if f.deferreturn == 0 {
1017+
throw("no deferreturn")
1018+
}
1019+
p.retpc = f.entry() + uintptr(f.deferreturn)
1020+
10211021
break // found a frame with linked defers
10221022
}
10231023

@@ -1273,15 +1273,6 @@ func recovery(gp *g) {
12731273
pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
12741274
p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0
12751275

1276-
// The linker records the f-relative address of a call to deferreturn in f's funcInfo.
1277-
// Assuming a "normal" call to recover() inside one of f's deferred functions
1278-
// invoked for a panic, that is the desired PC for exiting f.
1279-
f := findfunc(pc)
1280-
if f.deferreturn == 0 {
1281-
throw("no deferreturn")
1282-
}
1283-
gotoPc := f.entry() + uintptr(f.deferreturn)
1284-
12851276
// Unwind the panic stack.
12861277
for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
12871278
// Don't allow jumping past a pending Goexit.
@@ -1304,7 +1295,7 @@ func recovery(gp *g) {
13041295
// With how subtle defer handling is, this might not actually be
13051296
// worthwhile though.
13061297
if p.goexit {
1307-
gotoPc, sp = p.startPC, uintptr(p.startSP)
1298+
pc, sp = p.startPC, uintptr(p.startSP)
13081299
saveOpenDeferState = false // goexit is unwinding the stack anyway
13091300
break
13101301
}
@@ -1367,7 +1358,7 @@ func recovery(gp *g) {
13671358

13681359
// branch directly to the deferreturn
13691360
gp.sched.sp = sp
1370-
gp.sched.pc = gotoPc
1361+
gp.sched.pc = pc
13711362
gp.sched.lr = 0
13721363
// Restore the bp on platforms that support frame pointers.
13731364
// N.B. It's fine to not set anything for platforms that don't

src/runtime/runtime2.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,6 @@ type _defer struct {
10901090
heap bool
10911091
rangefunc bool // true for rangefunc list
10921092
sp uintptr // sp at time of defer
1093-
pc uintptr // pc at time of defer
10941093
fn func() // can be nil for open-coded defers
10951094
link *_defer // next defer on G; can point to either heap or stack!
10961095

0 commit comments

Comments
 (0)