aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/devirtualize
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2023-11-16 14:58:37 -0500
committerMichael Pratt <mpratt@google.com>2023-11-16 21:31:06 +0000
commit3fd5c357a3a763f70f3ed684caed878e732e6ebe (patch)
treeb9d9367b6bf0473407b4416affcd47f74cd43fcb /src/cmd/compile/internal/devirtualize
parente62bf150cc0802b3697da315ee41e19c0bbfb7eb (diff)
downloadgo-3fd5c357a3a763f70f3ed684caed878e732e6ebe.tar.xz
cmd/compile: don't devirtualize calls to runtime.memhash_varlen
runtime.memhash_varlen is defined as a normal function, but it is actually a closure. All references are generated by cmd/compile/internal/reflectdata.genhash, which creates a closure containing the size of the type, which memhash_varlen accesses with runtime.getclosureptr. Since this doesn't look like a normal closure, ir.Func.OClosure is not set, thus PGO function value devirtualization is willing to devirtualize it, generating a call that completely ignores the closure context. This causes memhash_varlen to either crash or generate incorrect results. Skip this function, which is the only caller of getclosureptr. Unfortunately there isn't a good way to detect these ineligible functions more generally. Fixes #64209. Change-Id: Ibf509406667c6d4e5d431f10e5b1d1f926ecd7dc Reviewed-on: https://go-review.googlesource.com/c/go/+/543195 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/compile/internal/devirtualize')
-rw-r--r--src/cmd/compile/internal/devirtualize/pgo.go9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/devirtualize/pgo.go b/src/cmd/compile/internal/devirtualize/pgo.go
index 0a34e7eb8d..7b6c8ba0c0 100644
--- a/src/cmd/compile/internal/devirtualize/pgo.go
+++ b/src/cmd/compile/internal/devirtualize/pgo.go
@@ -241,6 +241,15 @@ func maybeDevirtualizeFunctionCall(p *pgo.Profile, fn *ir.Func, call *ir.CallExp
}
return nil, nil, 0
}
+ // runtime.memhash_varlen does not look like a closure, but it uses
+ // runtime.getclosureptr to access data encoded by callers, which are
+ // are generated by cmd/compile/internal/reflectdata.genhash.
+ if callee.Sym().Pkg.Path == "runtime" && callee.Sym().Name == "memhash_varlen" {
+ if base.Debug.PGODebug >= 3 {
+ fmt.Printf("callee %s is a closure (runtime.memhash_varlen), skipping\n", ir.FuncName(callee))
+ }
+ return nil, nil, 0
+ }
// TODO(prattmic): We don't properly handle methods as callees in two
// different dimensions:
//