From: Michael Anthony Knyszek Date: Wed, 4 May 2022 19:48:29 +0000 (+0000) Subject: runtime/internal/atomic: align 64-bit types to 8 bytes everywhere X-Git-Tag: go1.19beta1~268 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0f715f1ac9565a0e932acf69a69414e3964e38c8;p=gostls13.git runtime/internal/atomic: align 64-bit types to 8 bytes everywhere This change extends https://go.dev/cl/381317 to the runtime/internal/atomic package in terms of aligning 64-bit types to 8 bytes, even on 32-bit platforms. Change-Id: Id8c45577d07b256e3144d88b31f201264295cfcd Reviewed-on: https://go-review.googlesource.com/c/go/+/404096 Reviewed-by: David Chase TryBot-Result: Gopher Robot Run-TryBot: Michael Knyszek --- diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go index 7122b2720f..a5a5c0b5b1 100644 --- a/src/cmd/compile/internal/types/size.go +++ b/src/cmd/compile/internal/types/size.go @@ -169,7 +169,7 @@ func calcStructOffset(errtype *Type, t *Type, o int64, flag int) int64 { } // Special case: sync/atomic.align64 is an empty struct we recognize // as a signal that the struct it contains must be 64-bit-aligned. - if isStruct && t.NumFields() == 0 && t.Sym() != nil && t.Sym().Name == "align64" && isSyncAtomic(t.Sym().Pkg) { + if isStruct && t.NumFields() == 0 && t.Sym() != nil && t.Sym().Name == "align64" && isAtomicStdPkg(t.Sym().Pkg) { maxalign = 8 } lastzero := int64(0) @@ -231,8 +231,9 @@ func calcStructOffset(errtype *Type, t *Type, o int64, flag int) int64 { return o } -func isSyncAtomic(p *Pkg) bool { - return p.Prefix == "sync/atomic" || p.Prefix == `""` && base.Ctxt.Pkgpath == "sync/atomic" +func isAtomicStdPkg(p *Pkg) bool { + return (p.Prefix == "sync/atomic" || p.Prefix == `""` && base.Ctxt.Pkgpath == "sync/atomic") || + (p.Prefix == "runtime/internal/atomic" || p.Prefix == `""` && base.Ctxt.Pkgpath == "runtime/internal/atomic") } // CalcSize calculates and stores the size and alignment for t. diff --git a/src/runtime/internal/atomic/types.go b/src/runtime/internal/atomic/types.go index d9cffbf88f..d346a76b67 100644 --- a/src/runtime/internal/atomic/types.go +++ b/src/runtime/internal/atomic/types.go @@ -49,9 +49,12 @@ func (i *Int32) Add(delta int32) int32 { // Int64 is an atomically accessed int64 value. // +// 8-byte aligned on all platforms, unlike a regular int64. +// // An Int64 must not be copied. type Int64 struct { noCopy noCopy + _ align64 value int64 } @@ -242,9 +245,12 @@ func (u *Uint32) Add(delta int32) uint32 { // Uint64 is an atomically accessed uint64 value. // +// 8-byte aligned on all platforms, unlike a regular uint64. +// // A Uint64 must not be copied. type Uint64 struct { noCopy noCopy + _ align64 value uint64 } @@ -346,9 +352,11 @@ func (u *Uintptr) Add(delta uintptr) uintptr { // Float64 is an atomically accessed float64 value. // +// 8-byte aligned on all platforms, unlike a regular float64. +// // A Float64 must not be copied. type Float64 struct { - // Inherits noCopy from Uint64. + // Inherits noCopy and align64 from Uint64. u Uint64 } @@ -416,3 +424,8 @@ type noCopy struct{} // Lock is a no-op used by -copylocks checker from `go vet`. func (*noCopy) Lock() {} func (*noCopy) Unlock() {} + +// align64 may be added to structs that must be 64-bit aligned. +// This struct is recognized by a special case in the compiler +// and will not work if copied to any other package. +type align64 struct{}