Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: gcWriteBarrier implementations assume argument slots are immutable #25512

Closed
mundaym opened this issue May 23, 2018 · 3 comments

Comments

Projects
None yet
4 participants
@mundaym
Copy link
Member

commented May 23, 2018

gcWriteBarrier currently promises to preserve all general purpose registers. It does this by saving the general purpose registers to the stack. However it saves its arguments into the argument slots for gcBufFlush and then restores them from the same slots. This isn't technically correct. As @randall77 mentioned in this post:

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.

This should probably be fixed for correctness. We could either mark gcWriteBarrier as clobbering its argument registers and then not bothering to restore them at all or we can save them to the stack somewhere else.

Examples of unsafe restores:

amd64:

go/src/runtime/asm_amd64.s

Lines 1451 to 1455 in 5776bd5

// This takes arguments DI and AX
CALL runtime·wbBufFlush(SB)
MOVQ 0(SP), DI
MOVQ 8(SP), AX

s390x:

go/src/runtime/asm_s390x.s

Lines 862 to 865 in 5776bd5

// This takes arguments R2 and R3.
CALL runtime·wbBufFlush(SB)
LMG 8(R15), R2, R3 // restore R2 - R3

@mundaym

This comment has been minimized.

Copy link
Member Author

commented May 23, 2018

@andybons andybons added this to the Unplanned milestone May 23, 2018

@cherrymui

This comment has been minimized.

Copy link
Contributor

commented May 23, 2018

I remember @aclements and I talked about this in the review of the buffered write barrier CL or somewhere. We decided this was ok. wbBufFlush was special enough and we can carefully code it so the argument slots are not clobbered. Probably still good to have a comment.

@gopherbot

This comment has been minimized.

Copy link

commented Aug 3, 2018

Change https://golang.org/cl/127815 mentions this issue: runtime: document assumption about wbBufFlush argument slots

@gopherbot gopherbot closed this in b800f20 Aug 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.