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
Closed
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@mundaym
Copy link
Member

mundaym 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
Copy link
Member Author

mundaym commented May 23, 2018

/cc @aclements

@andybons andybons added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 23, 2018
@andybons andybons added this to the Unplanned milestone May 23, 2018
@cherrymui
Copy link
Member

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
Copy link

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

@golang golang locked and limited conversation to collaborators Aug 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants