mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: move pcvalue cache to M
Currently, the pcvalue cache is stack allocated for each operation that needs to look up a lot of pcvalues. It's not always clear where to put it, a lot of the time we just pass a nil cache, it doesn't get reused across operations, and we put a surprising amount of effort into threading these caches around. This CL moves it to the M, where it can be long-lived and used by all pcvalue lookups, and we don't have to carefully thread it across operations. Change-Id: I675e583e0daac887c8ef77a402ba792648d96027 Reviewed-on: https://go-review.googlesource.com/c/go/+/515276 Run-TryBot: Austin Clements <austin@google.com> Auto-Submit: Austin Clements <austin@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
parent
6be2639aff
commit
d367ec6a0e
2 changed files with 27 additions and 22 deletions
|
|
@ -611,6 +611,9 @@ type m struct {
|
||||||
// Whether this is a pending preemption signal on this M.
|
// Whether this is a pending preemption signal on this M.
|
||||||
signalPending atomic.Uint32
|
signalPending atomic.Uint32
|
||||||
|
|
||||||
|
// pcvalue lookup cache
|
||||||
|
pcvalueCache pcvalueCache
|
||||||
|
|
||||||
dlogPerM
|
dlogPerM
|
||||||
|
|
||||||
mOS
|
mOS
|
||||||
|
|
|
||||||
|
|
@ -843,30 +843,32 @@ func pcvalueCacheKey(targetpc uintptr) uintptr {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the PCData value, and the PC where this value starts.
|
// 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) {
|
func pcvalue(f funcInfo, off uint32, targetpc uintptr, _ *pcvalueCache, strict bool) (int32, uintptr) {
|
||||||
if off == 0 {
|
if off == 0 {
|
||||||
return -1, 0
|
return -1, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the cache. This speeds up walks of deep stacks, which
|
// Check the cache. This speeds up walks of deep stacks, which
|
||||||
// tend to have the same recursive functions over and over.
|
// tend to have the same recursive functions over and over,
|
||||||
//
|
// or repetitive stacks between goroutines.
|
||||||
// This cache is small enough that full associativity is
|
ck := pcvalueCacheKey(targetpc)
|
||||||
// cheaper than doing the hashing for a less associative
|
{
|
||||||
// cache.
|
mp := acquirem()
|
||||||
if cache != nil {
|
cache := &mp.pcvalueCache
|
||||||
x := pcvalueCacheKey(targetpc)
|
for i := range cache.entries[ck] {
|
||||||
for i := range cache.entries[x] {
|
|
||||||
// We check off first because we're more
|
// We check off first because we're more
|
||||||
// likely to have multiple entries with
|
// likely to have multiple entries with
|
||||||
// different offsets for the same targetpc
|
// different offsets for the same targetpc
|
||||||
// than the other way around, so we'll usually
|
// than the other way around, so we'll usually
|
||||||
// fail in the first clause.
|
// fail in the first clause.
|
||||||
ent := &cache.entries[x][i]
|
ent := &cache.entries[ck][i]
|
||||||
if ent.off == off && ent.targetpc == targetpc {
|
if ent.off == off && ent.targetpc == targetpc {
|
||||||
return ent.val, ent.valPC
|
val, pc := ent.val, ent.valPC
|
||||||
|
releasem(mp)
|
||||||
|
return val, pc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
releasem(mp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.valid() {
|
if !f.valid() {
|
||||||
|
|
@ -894,10 +896,10 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, stri
|
||||||
// larger than the cache.
|
// larger than the cache.
|
||||||
// Put the new element at the beginning,
|
// Put the new element at the beginning,
|
||||||
// since it is the most likely to be newly used.
|
// since it is the most likely to be newly used.
|
||||||
if cache != nil {
|
mp := acquirem()
|
||||||
x := pcvalueCacheKey(targetpc)
|
cache := &mp.pcvalueCache
|
||||||
e := &cache.entries[x]
|
e := &cache.entries[ck]
|
||||||
ci := fastrandn(uint32(len(cache.entries[x])))
|
ci := fastrandn(uint32(len(cache.entries[ck])))
|
||||||
e[ci] = e[0]
|
e[ci] = e[0]
|
||||||
e[0] = pcvalueCacheEnt{
|
e[0] = pcvalueCacheEnt{
|
||||||
targetpc: targetpc,
|
targetpc: targetpc,
|
||||||
|
|
@ -905,7 +907,7 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, stri
|
||||||
val: val,
|
val: val,
|
||||||
valPC: prevpc,
|
valPC: prevpc,
|
||||||
}
|
}
|
||||||
}
|
releasem(mp)
|
||||||
|
|
||||||
return val, prevpc
|
return val, prevpc
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue