mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[release-branch.go1.24] cmd/compile: fix out of memory when inlining closure
CL 629195 strongly favor closure inlining, allowing closures to be inlined more aggressively. However, if the closure body contains a call to a function, which itself is one of the call arguments, it causes the infinite inlining. Fixing this by prevent this kind of functions from being inlinable. Fixes #72067 Change-Id: I5fb5723a819b1e2c5aadb57c1023ec84ca9fa53c Reviewed-on: https://go-review.googlesource.com/c/go/+/654195 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/654517 Commit-Queue: Junyang Shao <shaojunyang@google.com> Auto-Submit: Junyang Shao <shaojunyang@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
This commit is contained in:
parent
e4119e9b74
commit
0ace2d8aca
2 changed files with 62 additions and 0 deletions
|
|
@ -1040,6 +1040,28 @@ func canInlineCallExpr(callerfn *ir.Func, n *ir.CallExpr, callee *ir.Func, bigCa
|
|||
return false, 0, false
|
||||
}
|
||||
}
|
||||
do := func(fn *ir.Func) bool {
|
||||
// Can't recursively inline a function if the function body contains
|
||||
// a call to a function f, which the function f is one of the call arguments.
|
||||
return ir.Any(fn, func(node ir.Node) bool {
|
||||
if call, ok := node.(*ir.CallExpr); ok {
|
||||
for _, arg := range call.Args {
|
||||
if call.Fun == arg {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
for _, fn := range []*ir.Func{callerfn, callee} {
|
||||
if do(fn) {
|
||||
if log && logopt.Enabled() {
|
||||
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to function: %s", ir.FuncName(fn)))
|
||||
}
|
||||
return false, 0, false
|
||||
}
|
||||
}
|
||||
|
||||
if base.Flag.Cfg.Instrumenting && types.IsNoInstrumentPkg(callee.Sym().Pkg) {
|
||||
// Runtime package must not be instrumented.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue