aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/symtab.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2023-08-16 12:30:10 -0400
committerGopher Robot <gobot@golang.org>2023-08-20 17:52:59 +0000
commite094e80f65f77bf83e2962dc5150915711f2166d (patch)
tree6baae8b2b93dbbe752a0699e5c79193b7d79594a /src/runtime/symtab.go
parent9ac6b00e79312e5ad4665acc063ac7b77becddf8 (diff)
downloadgo-e094e80f65f77bf83e2962dc5150915711f2166d.tar.xz
runtime: add self-check mode to cache in pcvalue
This would have helped with debugging the failures caused by CL 515276. Change-Id: Id641949d8bcd763de7f93778ad9bd3fdde95dcb2 Reviewed-on: https://go-review.googlesource.com/c/go/+/520062 Auto-Submit: Austin Clements <austin@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/symtab.go')
-rw-r--r--src/runtime/symtab.go20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index ff5f5f7f0e..d828c37a75 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -844,6 +844,10 @@ func pcvalueCacheKey(targetpc uintptr) uintptr {
// Returns the PCData value, and the PC where this value starts.
func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
+ // If true, when we get a cache hit, still look up the data and make sure it
+ // matches the cached contents.
+ const debugCheckCache = false
+
if off == 0 {
return -1, 0
}
@@ -854,6 +858,8 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, stri
// This cache is small enough that full associativity is
// cheaper than doing the hashing for a less associative
// cache.
+ var checkVal int32
+ var checkPC uintptr
if cache != nil {
x := pcvalueCacheKey(targetpc)
for i := range cache.entries[x] {
@@ -864,7 +870,12 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, stri
// fail in the first clause.
ent := &cache.entries[x][i]
if ent.off == off && ent.targetpc == targetpc {
- return ent.val, ent.valPC
+ if debugCheckCache {
+ checkVal, checkPC = ent.val, ent.valPC
+ break
+ } else {
+ return ent.val, ent.valPC
+ }
}
}
}
@@ -894,7 +905,12 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, stri
// larger than the cache.
// Put the new element at the beginning,
// since it is the most likely to be newly used.
- if cache != nil {
+ if debugCheckCache && checkPC != 0 {
+ if checkVal != val || checkPC != prevpc {
+ print("runtime: table value ", val, "@", prevpc, " != cache value ", checkVal, "@", checkPC, " at PC ", targetpc, " off ", off, "\n")
+ throw("bad pcvalue cache")
+ }
+ } else if cache != nil {
x := pcvalueCacheKey(targetpc)
e := &cache.entries[x]
ci := fastrandn(uint32(len(cache.entries[x])))