]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use entry stack map at function entry
authorAustin Clements <austin@google.com>
Wed, 25 Apr 2018 20:53:04 +0000 (16:53 -0400)
committerAustin Clements <austin@google.com>
Sun, 29 Apr 2018 00:03:04 +0000 (00:03 +0000)
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>
src/runtime/heapdump.go
src/runtime/mbitmap.go
src/runtime/mgcmark.go
src/runtime/stack.go

index b255cbbae39b9fbc7d9f20c6eb7cc9fb2abb01c7..2b8937834c573b109969e18ba34e8b9dcb6f8622 100644 (file)
@@ -248,10 +248,11 @@ func dumpframe(s *stkframe, arg unsafe.Pointer) bool {
 
        // Figure out what we can about our stack map
        pc := s.pc
+       pcdata := int32(-1) // Use the entry map at function entry
        if pc != f.entry {
                pc--
+               pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, pc, nil)
        }
-       pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, pc, nil)
        if pcdata == -1 {
                // We do not have a valid pcdata value but there might be a
                // stackmap for this function. It is likely that we are looking
index 38d994eb5a2bd461993caf9d0ef0ed4bb9fe0c73..69bd0b502b07778a1b7ef4221591397e3db31aa9 100644 (file)
@@ -2004,10 +2004,11 @@ func getgcmask(ep interface{}) (mask []byte) {
                        if targetpc == 0 {
                                return
                        }
+                       pcdata := int32(-1) // Use the entry map at function entry
                        if targetpc != f.entry {
                                targetpc--
+                               pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, nil)
                        }
-                       pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, nil)
                        if pcdata == -1 {
                                return
                        }
index 270fa6cd32c8fb7794f982c0427646a9464e2d1a..7be28209095c2fe8418419bb9d2cc6df18537007 100644 (file)
@@ -801,10 +801,15 @@ func scanframeworker(frame *stkframe, cache *pcvalueCache, gcw *gcWork) {
        if _DebugGC > 1 {
                print("scanframe ", funcname(f), "\n")
        }
+       pcdata := int32(-1)
        if targetpc != f.entry {
+               // Back up to the CALL. If we're at the function entry
+               // point, we want to use the entry map (-1), even if
+               // the first instruction of the function changes the
+               // stack map.
                targetpc--
+               pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
        }
-       pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
        if pcdata == -1 {
                // We do not have a valid pcdata value but there might be a
                // stackmap for this function. It is likely that we are looking
index 63a286bf592ec2f5d8450730a3384c0eb3f02a83..2d10ac83817eed8a3ac11352fb7e2793d602bae7 100644 (file)
@@ -625,10 +625,11 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
                // have full GC info for it (because it is written in asm).
                return true
        }
+       pcdata := int32(-1) // Use the entry map at function entry
        if targetpc != f.entry {
                targetpc--
+               pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, &adjinfo.cache)
        }
-       pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, &adjinfo.cache)
        if pcdata == -1 {
                pcdata = 0 // in prologue
        }