calling convention: are func args (passed on the stack) mutable by callee?

303 views
Skip to first unread message

Nigel Tao

unread,
Aug 30, 2016, 2:27:03 AM8/30/16
to golang-dev
I have some asm code that looks like:

// Args.
MOVQ DI, 0(SP)
MOVQ SI, 8(SP)
MOVQ CX, 16(SP)
// Spill registers.
MOVQ DI, 24(SP)
MOVQ SI, 32(SP)
MOVQ CX, 40(SP)
CALL runtime·memmove(SB)
// Unspill registers.
MOVQ 24(SP), DI
MOVQ 32(SP), SI
MOVQ 40(SP), CX

The DI, SI and CX registers are stored twice, and at first glance, it
looks redundant. The first set is because they are arguments to the
runtime·memmove function. The second set is because I need to restore
them after the call.

I have a pull request (https://github.com/golang/snappy/pull/35) to
only store them once, and restore them from the function args.
However, this assumes that the callee will not modify the stack memory
where those arguments were passed.

Even if this was true specifically for the runtime·memmove function,
I'd rather not rely on that unless, in general, the Go calling
convention is that the callee should not modify the args on the stack.
(Obviously, they are allowed to modify the return value on the stack).

Is that definitively true or not true? I skimmed
https://golang.org/doc/asm and didn't find an answer.

Keith Randall

unread,
Aug 30, 2016, 2:36:15 AM8/30/16
to Nigel Tao, golang-dev
The Go calling convention allows the callee to modify the argument slots on the stack.  The caller must not assume that they are unmodified across a call.
The compiler does in fact use the argument slots for spill locations.  For example:
func f(x int) int {
x++
runtime.GC()
return x
}
The x+1 value will be spilled to x's argument slot across the runtime.GC() call.

That said, you're probably ok with memmove.



--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Damian Gryski

unread,
Aug 30, 2016, 5:54:39 AM8/30/16
to golang-dev, nige...@golang.org


On Tuesday, August 30, 2016 at 8:36:15 AM UTC+2, Keith Randall wrote:
The Go calling convention allows the callee to modify the argument slots on the stack.  The caller must not assume that they are unmodified across a call.
The compiler does in fact use the argument slots for spill locations.  For example:
func f(x int) int {
x++
runtime.GC()
return x
}
The x+1 value will be spilled to x's argument slot across the runtime.GC() call.

The specifics of the calling convention should probably be added to the /doc/asm, even if they have the same `unsafe` "We reserve the right to break this at any time." disclaimer.

Damian
Reply all
Reply to author
Forward
0 new messages