diff options
author | Austin Clements <austin@google.com> | 2017-11-15 14:54:24 -0800 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2018-02-13 16:34:15 +0000 |
commit | 252f1170e5f13d9b12ec3a117ca2bb2241f74c08 (patch) | |
tree | e5f838e642f2caea342a13144efc9cda6934ca1e /src/runtime/asm_386.s | |
parent | de186c63ce058b2ab43f324fe582dc2ab1369614 (diff) | |
download | go-252f1170e5f13d9b12ec3a117ca2bb2241f74c08.tar.gz go-252f1170e5f13d9b12ec3a117ca2bb2241f74c08.zip |
runtime: buffered write barrier for 386
Updates #22460.
Change-Id: I3c8e90fd6bcda7e28911036591873d63665aaca7
Reviewed-on: https://go-review.googlesource.com/92696
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime/asm_386.s')
-rw-r--r-- | src/runtime/asm_386.s | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index 80a145187c..ee6d768c23 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -1695,3 +1695,61 @@ TEXT runtime·float64touint32(SB),NOSPLIT,$12-12 MOVL 4(SP), AX MOVL AX, ret+8(FP) RET + +// gcWriteBarrier performs a heap pointer write and informs the GC. +// +// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments: +// - DI is the destination of the write +// - AX is the value being written at DI +// It clobbers FLAGS. It does not clobber any general-purpose registers, +// but may clobber others (e.g., SSE registers). +TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$28 + // Save the registers clobbered by the fast path. This is slightly + // faster than having the caller spill these. + MOVL CX, 20(SP) + MOVL BX, 24(SP) + // TODO: Consider passing g.m.p in as an argument so they can be shared + // across a sequence of write barriers. + get_tls(BX) + MOVL g(BX), BX + MOVL g_m(BX), BX + MOVL m_p(BX), BX + MOVL (p_wbBuf+wbBuf_next)(BX), CX + // Increment wbBuf.next position. + LEAL 8(CX), CX + MOVL CX, (p_wbBuf+wbBuf_next)(BX) + CMPL CX, (p_wbBuf+wbBuf_end)(BX) + // Record the write. + MOVL AX, -8(CX) // Record value + MOVL (DI), BX // TODO: This turns bad writes into bad reads. + MOVL BX, -4(CX) // Record *slot + // Is the buffer full? (flags set in CMPL above) + JEQ flush +ret: + MOVL 20(SP), CX + MOVL 24(SP), BX + // Do the write. + MOVL AX, (DI) + RET + +flush: + // Save all general purpose registers since these could be + // clobbered by wbBufFlush and were not saved by the caller. + MOVL DI, 0(SP) // Also first argument to wbBufFlush + MOVL AX, 4(SP) // Also second argument to wbBufFlush + // BX already saved + // CX already saved + MOVL DX, 8(SP) + MOVL BP, 12(SP) + MOVL SI, 16(SP) + // DI already saved + + // This takes arguments DI and AX + CALL runtime·wbBufFlush(SB) + + MOVL 0(SP), DI + MOVL 4(SP), AX + MOVL 8(SP), DX + MOVL 12(SP), BP + MOVL 16(SP), SI + JMP ret |