]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/internal/atomic: align 64-bit types to 8 bytes everywhere
authorMichael Anthony Knyszek <mknyszek@google.com>
Wed, 4 May 2022 19:48:29 +0000 (19:48 +0000)
committerMichael Knyszek <mknyszek@google.com>
Fri, 13 May 2022 16:02:27 +0000 (16:02 +0000)
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 <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Knyszek <mknyszek@google.com>

src/cmd/compile/internal/types/size.go
src/runtime/internal/atomic/types.go

index 7122b2720ff5bfeb63edbe263b0406d734958b94..a5a5c0b5b1442e3c35c1d89f2e9c5d0947da9391 100644 (file)
@@ -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.
index d9cffbf88fa519cfddd9251617df5b56d9181047..d346a76b67c10de95b3d44d8b9f21e2a0991ee53 100644 (file)
@@ -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{}