cmd/compile: make 64-bit fields 64-bit aligned on 32-bit systems #599

Open
rsc opened this Issue Feb 12, 2010 · 23 comments

Projects

None yet

7 participants

@rsc
Contributor
rsc commented Feb 12, 2010
Even though the 386 has a 4-byte word size, some instructions move 
data in larger chunks.  In particular float64 loads move 8 bytes and
some SSE2 operations (as yet unused) move even larger amounts.
A float64 load from an only-4-byte-aligned address is significantly
more expensive than one from a 8-byte-aligned address.  The same
is probably true of SSE2 too.

We should make sure that data symbols >32 bits (e.g., float64 constants)
are aligned on 8-byte boundaries in the data segment.  (Fairly easy.)

We should also make sure that the stack pointer can be relied upon to be
8-byte aligned (harder), by making stack frame sizes = -4 mod 8 
(the caller PC will add 4 more) and starting new goroutines with a
properly aligned stack pointer.

It might be worth using 16 bytes for the stack alignment.  OS X requires
that for their own ABI, presumably because it matters for SSE2.
@rsc
Contributor
rsc commented Dec 9, 2011

Comment 1:

Labels changed: added priority-someday.

@rsc
Contributor
rsc commented Sep 12, 2012

Comment 2:

Issue #3799 has been merged into this issue.

@rsc
Contributor
rsc commented Sep 12, 2012

Comment 3:

This is necessary for atomics to work correctly.
@rsc
Contributor
rsc commented Sep 12, 2012

Comment 4:

Labels changed: added priority-soon, removed priority-someday.

Status changed to Accepted.

@rsc
Contributor
rsc commented Sep 12, 2012

Comment 5:

Labels changed: added go1.1.

@rsc
Contributor
rsc commented Dec 10, 2012

Comment 7:

Labels changed: added size-l.

@rsc
Contributor
rsc commented Dec 22, 2012

Comment 8:

Too hard. I tried a few different things and failed miserably. The gc toolchain expects
that the struct and function argument frame alignments match. The stack frame 
barely matters, since we don't take pointers of stack variables anymore, but that's
hard too.
This only really matters for atomics, and we do guarantee 64-bit alignment for the
base of an allocated struct or slice, so that will have to be good enough for now.

Labels changed: added priority-someday, removed priority-soon, go1.1.

@rsc
Contributor
rsc commented Dec 22, 2012

Comment 9:

Labels changed: added size-xl, removed size-l.

@rsc
Contributor
rsc commented Jul 30, 2013

Comment 10:

Labels changed: added go1.3maybe.

@robpike
Contributor
robpike commented Aug 20, 2013

Comment 11:

Labels changed: removed go1.3maybe.

@rsc
Contributor
rsc commented Oct 29, 2013

Comment 13:

I have had an opportunity to revisit this problem recently in a different context. I
think we can do it for Go 1.3.

Labels changed: added go1.3.

@rsc
Contributor
rsc commented Dec 4, 2013

Comment 14:

Labels changed: added release-go1.3.

@rsc
Contributor
rsc commented Dec 4, 2013

Comment 15:

Labels changed: removed go1.3.

@rsc
Contributor
rsc commented Dec 4, 2013

Comment 16:

Labels changed: added repo-main.

@rsc
Contributor
rsc commented Apr 3, 2014

Comment 17:

We didn't do it for 1.3. My guess is that in comment 13 I was referring to NaCl having
unusual alignment requirements, so perhaps that would pave the way.

Labels changed: added release-go1.4, removed release-go1.3.

@rsc
Contributor
rsc commented Sep 15, 2014

Comment 18:

Labels changed: added release-none, removed release-go1.4.

@rsc rsc self-assigned this Sep 15, 2014
@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc changed the title from cmd/5c, 5g, 8c, 8g: make 64-bit fields 64-bit aligned to cmd/compile: make 64-bit fields 64-bit aligned on 32-bit systems Jun 8, 2015
@andrewpsuedonym

Is this still an issue on go 1.5?

@davecheney
Contributor

Is this still an issue on go 1.5?

Yes. This issue is still open, and has not been assigned a release milestone.

@kardianos
Contributor

Status: right now there does not appear to be motivation to remove the BUG in the docs and close the issue or ensure struct alignment by the compiler: https://groups.google.com/forum/#!topic/golang-dev/cUju6W3nWEU

@gopherbot

CL https://golang.org/cl/34193 mentions this issue.

@gopherbot gopherbot pushed a commit that closed this issue Dec 12, 2016
@minux @minux minux + minux cmd/internal/obj/mips: replace MOVD with MOVF on 32-bit to avoid unal…
…igned memory access

This is the simplest CL that I can make for Go 1.8. For Go 1.9, we can revisit it
and optimize the redundant address generation instructions or just fix #599 instead.

Fixes #18140.

Change-Id: Ie4804ab0e00dc6bb318da2bece8035c7c71caac3
Reviewed-on: https://go-review.googlesource.com/34193
Run-TryBot: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
9fe2291
@gopherbot gopherbot closed this in 9fe2291 Dec 12, 2016
@davecheney davecheney reopened this Dec 12, 2016
@bradfitz
Member

@davecheney, what's the background for reopening this?

@davecheney
Contributor
davecheney commented Dec 12, 2016 edited

9fe2291 closes issue #18140, not this one

cmd/internal/obj/mips: replace MOVD with MOVF on 32-bit to avoid unaligned memory access

This is the simplest CL that I can make for Go 1.8. For Go 1.9, we can revisit it
and optimize the redundant address generation instructions or just fix #599 instead.

Fixes #18140.
@bradfitz
Member

Hah, thanks.

@spacewrangler spacewrangler added a commit to spacewrangler/beats that referenced this issue Jan 8, 2017
@spacewrangler spacewrangler Ensure harvesterCounter 8-byte alignment (#3273)
harvesterCounter is accessed atomically and will fault on x86-32 or ARM if not 8-byte aligned. See golang/go#599 for more details on why it fails and https://golang.org/pkg/sync/atomic/#pkg-note-BUG for how putting the field first in the struct fixes it.
8b99044
@spacewrangler spacewrangler pushed a commit to spacewrangler/beats that referenced this issue Jan 11, 2017
Jon Langdon Ensure harvesterCounter 8-byte alignment (#3273)
harvesterCounter is accessed atomically and will fault on x86-32 or ARM
if not 8-byte aligned. See golang/go#599 for more details on why it
fails and https://golang.org/pkg/sync/atomic/#pkg-note-BUG for how
putting the field first in the struct fixes it.
1584a29
@tsg tsg added a commit to elastic/beats that referenced this issue Jan 13, 2017
@spacewrangler @tsg spacewrangler + tsg Ensure harvesterCounter 8-byte alignment (#3273) (#3338)
harvesterCounter is accessed atomically and will fault on x86-32 or ARM
if not 8-byte aligned. See golang/go#599 for more details on why it
fails and https://golang.org/pkg/sync/atomic/#pkg-note-BUG for how
putting the field first in the struct fixes it.
fd64af2
@tsg tsg added a commit to tsg/beats that referenced this issue Jan 13, 2017
@spacewrangler @tsg spacewrangler + tsg Ensure harvesterCounter 8-byte alignment (#3273) (#3338)
harvesterCounter is accessed atomically and will fault on x86-32 or ARM
if not 8-byte aligned. See golang/go#599 for more details on why it
fails and https://golang.org/pkg/sync/atomic/#pkg-note-BUG for how
putting the field first in the struct fixes it.
(cherry picked from commit fd64af2)
ff009ed
@ruflin ruflin added a commit to elastic/beats that referenced this issue Jan 13, 2017
@tsg @ruflin tsg + ruflin Backport 3338 to the 5.2 branch (#3364)
* Ensure harvesterCounter 8-byte alignment (#3273) (#3338)

harvesterCounter is accessed atomically and will fault on x86-32 or ARM
if not 8-byte aligned. See golang/go#599 for more details on why it
fails and https://golang.org/pkg/sync/atomic/#pkg-note-BUG for how
putting the field first in the struct fixes it.
(cherry picked from commit fd64af2)

* Follow up with changelog for 3338 (#3363)

(cherry picked from commit 03b70c3)
c140992
@fomojola fomojola added a commit to fomojola/go-cast that referenced this issue Jan 15, 2017
@fomojola fomojola ARM compatibility
Added an unused int32 to the Channel structure. This fixes execution on ARM platforms (specifically Raspberry Pi) caused by golang/go#599. After cross-compiling for ARM using

GOOS=linux GOARM=6 GOARCH=arm go build github.com/barnybug/go-cast/cmd/cast

it appears that the call

requestId := int(atomic.AddInt64(&c.requestId, 1))

in Request() causes errors because the Channel structure isn't appropriately 64-bit aligned. The returned error looks like this:

pi@raspberrypi:~ $ ./cast --name chromecast media play 'http://192.168.2.22:8080/music/play.mp3"
Connecting to 192.168.2.42:8009...
Connected
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x4 pc=0x152894]

goroutine 1 [running]:
panic(0x332b60, 0x10824008)
	/usr/local/go/src/runtime/panic.go:500 +0x33c
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.HandleAction.func1(0x108f8f30)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:478 +0x290
panic(0x332b60, 0x10824008)
	/usr/local/go/src/runtime/panic.go:458 +0x454
sync/atomic.addUint64(0x1090159c, 0x1, 0x0, 0x1, 0x0)
	/usr/local/go/src/sync/atomic/64bit_arm.go:31 +0x68
github.com/barnybug/go-cast/net.(*Channel).Request(0x10901580, 0x76ef1120, 0x10816440, 0x495920, 0x4aa058, 0x141130, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/net/channel.go:77 +0x60
github.com/barnybug/go-cast/controllers.(*ReceiverController).GetStatus(0x108c5700, 0x76ef1120, 0x10816440, 0x0, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/controllers/receiver.go:150 +0x58
github.com/barnybug/go-cast.(*Client).launchMediaApp(0x10816900, 0x76ef1120, 0x10816440, 0x0, 0x0, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/client.go:133 +0x48
github.com/barnybug/go-cast.(*Client).Media(0x10816900, 0x76ef1120, 0x10816440, 0x4, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/client.go:171 +0x54
main.runCommand(0x76ef1120, 0x10816440, 0x10816900, 0x36447a, 0x4, 0x1080a0e8, 0x1, 0x1)
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:343 +0xc8
main.cliCommand(0x10878280)
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:128 +0x244
reflect.Value.call(0x31c8a0, 0x395e40, 0x13, 0x36428e, 0x4, 0x108f8ef0, 0x1, 0x1, 0x0, 0x0, ...)
	/usr/local/go/src/reflect/value.go:434 +0xd68
reflect.Value.Call(0x31c8a0, 0x395e40, 0x13, 0x108f8ef0, 0x1, 0x1, 0x0, 0x0, 0x0)
	/usr/local/go/src/reflect/value.go:302 +0x84
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.HandleAction(0x31c8a0, 0x395e40, 0x10878280, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:487 +0x1d0
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.Run(0x36447a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3676e2, 0xf, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:191 +0xc10
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.(*App).RunAsSubcommand(0x108883c0, 0x10878140, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:361 +0xd18
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.startApp(0x3647da, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3671f2, 0xe, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:278 +0x78c
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.Command.Run(0x3647da, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3671f2, 0xe, 0x0, ...)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/command.go:79 +0x54
github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli.(*App).Run(0x10888300, 0x1080a0c0, 0x6, 0x6, 0x0, 0x0)
	/workspace/src/github.com/barnybug/go-cast/vendor/github.com/codegangsta/cli/app.go:240 +0x798
main.main()
	/workspace/src/github.com/barnybug/go-cast/cmd/cast/main.go:116 +0x6a0

The addition of the unused int32 forces the alignment to adjust appropriately and prevents the runtime error.
c5014b1
@fomojola fomojola referenced this issue in barnybug/go-cast Jan 15, 2017
Merged

ARM compatibility #1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment