cmd/compile/internal/escape: escape values with >PtrSize alignment

After CL 381317 there exist values that may have an alignment greater
than the pointer size for that platform. Specifically, atomic.{Ui|I}nt64
may be aligned to 8 bytes on a 32-bit platform. If such a value, or
a container for the value, gets stack-allocated, it's possible that it
won't be aligned correctly, because the maximum alignment we enforce on
stacks is governed by the pointer size. Changing that would be a
significant undertaking, so just escape these values to the heap
instead, where we're sure they'll actually be aligned correctly.

Change is by rsc@, I'm just shepherding it through code review.

For #50860.

Change-Id: I51669561c0a13ecb84f821020e144c58cb528418
Reviewed-on: https://go-review.googlesource.com/c/go/+/410131
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Michael Anthony Knyszek 2022-06-03 19:15:24 +00:00 committed by Michael Knyszek
parent ee87cd1dd9
commit 162b88265e

View file

@ -7,6 +7,7 @@ package escape
import (
"cmd/compile/internal/ir"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
)
func isSliceSelfAssign(dst, src ir.Node) bool {
@ -185,10 +186,16 @@ func HeapAllocReason(n ir.Node) string {
if n.Type().Size() > ir.MaxStackVarSize {
return "too large for stack"
}
if n.Type().Alignment() > int64(types.PtrSize) {
return "too aligned for stack"
}
if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Size() > ir.MaxImplicitStackVarSize {
return "too large for stack"
}
if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Alignment() > int64(types.PtrSize) {
return "too aligned for stack"
}
if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() > ir.MaxImplicitStackVarSize {
return "too large for stack"