]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add self-check mode to cache in pcvalue
authorAustin Clements <austin@google.com>
Wed, 16 Aug 2023 16:30:10 +0000 (12:30 -0400)
committerGopher Robot <gobot@golang.org>
Sun, 20 Aug 2023 17:52:59 +0000 (17:52 +0000)
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>

src/runtime/symtab.go

index ff5f5f7f0ef4073fc9862891970d0aa3dd9a7b54..d828c37a75d326409bc31e608fc70e457cf8ef23 100644 (file)
@@ -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])))