Skip to content

Commit 0fd427f

Browse files
committed
runtime: use entry stack map at function entry
Currently, when the runtime looks up the stack map for a frame, it uses frame.continpc - 1 unless continpc is the function entry PC, in which case it uses frame.continpc. As a result, if continpc is the function entry point (which happens for deferred frames), it will actually look up the stack map *following* the first instruction. I think, though I am not positive, that this is always okay today because the first instruction of a function can never change the stack map. It's usually not a CALL, so it doesn't have PCDATA. Or, if it is a CALL, it has to have the entry stack map. But we're about to start emitting stack maps at every instruction that changes them, which means the first instruction can have PCDATA (notably, in leaf functions that don't have a prologue). To prepare for this, tweak how the runtime looks up stack map indexes so that if continpc is the function entry point, it directly uses the entry stack map. For #24543. Change-Id: I85aa818041cd26aff416f7b1fba186e9c8ca6568 Reviewed-on: https://go-review.googlesource.com/109349 Reviewed-by: Rick Hudson <rlh@golang.org>
1 parent 3c65bb5 commit 0fd427f

File tree

4 files changed

+12
-4
lines changed

4 files changed

+12
-4
lines changed

src/runtime/heapdump.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,11 @@ func dumpframe(s *stkframe, arg unsafe.Pointer) bool {
248248

249249
// Figure out what we can about our stack map
250250
pc := s.pc
251+
pcdata := int32(-1) // Use the entry map at function entry
251252
if pc != f.entry {
252253
pc--
254+
pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, pc, nil)
253255
}
254-
pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, pc, nil)
255256
if pcdata == -1 {
256257
// We do not have a valid pcdata value but there might be a
257258
// stackmap for this function. It is likely that we are looking

src/runtime/mbitmap.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -2004,10 +2004,11 @@ func getgcmask(ep interface{}) (mask []byte) {
20042004
if targetpc == 0 {
20052005
return
20062006
}
2007+
pcdata := int32(-1) // Use the entry map at function entry
20072008
if targetpc != f.entry {
20082009
targetpc--
2010+
pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, nil)
20092011
}
2010-
pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, nil)
20112012
if pcdata == -1 {
20122013
return
20132014
}

src/runtime/mgcmark.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -801,10 +801,15 @@ func scanframeworker(frame *stkframe, cache *pcvalueCache, gcw *gcWork) {
801801
if _DebugGC > 1 {
802802
print("scanframe ", funcname(f), "\n")
803803
}
804+
pcdata := int32(-1)
804805
if targetpc != f.entry {
806+
// Back up to the CALL. If we're at the function entry
807+
// point, we want to use the entry map (-1), even if
808+
// the first instruction of the function changes the
809+
// stack map.
805810
targetpc--
811+
pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
806812
}
807-
pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
808813
if pcdata == -1 {
809814
// We do not have a valid pcdata value but there might be a
810815
// stackmap for this function. It is likely that we are looking

src/runtime/stack.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,11 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
625625
// have full GC info for it (because it is written in asm).
626626
return true
627627
}
628+
pcdata := int32(-1) // Use the entry map at function entry
628629
if targetpc != f.entry {
629630
targetpc--
631+
pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, &adjinfo.cache)
630632
}
631-
pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, &adjinfo.cache)
632633
if pcdata == -1 {
633634
pcdata = 0 // in prologue
634635
}

0 commit comments

Comments
 (0)