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:21 +0000 |
commit | 313a4b2b7f6479f13c4d460aebe514aa86543e21 (patch) | |
tree | a608750561400f7e13c59c187ae17b2803fab81f /src/runtime/asm_mipsx.s | |
parent | a39de964385fb32d13d8fac3991a669de962f0bd (diff) | |
download | go-313a4b2b7f6479f13c4d460aebe514aa86543e21.tar.gz go-313a4b2b7f6479f13c4d460aebe514aa86543e21.zip |
runtime: buffered write barrier for mips
Updates #22460.
Change-Id: Ieaca94385c3bb88dcc8351c3866b4b0e2a1412b5
Reviewed-on: https://go-review.googlesource.com/92701
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_mipsx.s')
-rw-r--r-- | src/runtime/asm_mipsx.s | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s index 6a4eb0af25..47367f1703 100644 --- a/src/runtime/asm_mipsx.s +++ b/src/runtime/asm_mipsx.s @@ -856,3 +856,104 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1 MOVW $1, R1 MOVB R1, ret+0(FP) RET + +// gcWriteBarrier performs a heap pointer write and informs the GC. +// +// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments: +// - R20 is the destination of the write +// - R21 is the value being written at R20. +// It clobbers R23 (the linker temp register). +// The act of CALLing gcWriteBarrier will clobber R31 (LR). +// It does not clobber any other general-purpose registers, +// but may clobber others (e.g., floating point registers). +TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$104 + // Save the registers clobbered by the fast path. + MOVW R1, 100(R29) + MOVW R2, 104(R29) + MOVW g_m(g), R1 + MOVW m_p(R1), R1 + MOVW (p_wbBuf+wbBuf_next)(R1), R2 + // Increment wbBuf.next position. + ADD $8, R2 + MOVW R2, (p_wbBuf+wbBuf_next)(R1) + MOVW (p_wbBuf+wbBuf_end)(R1), R1 + MOVW R1, R23 // R23 is linker temp register + // Record the write. + MOVW R21, -8(R2) // Record value + MOVW (R20), R1 // TODO: This turns bad writes into bad reads. + MOVW R1, -4(R2) // Record *slot + // Is the buffer full? + BEQ R2, R23, flush +ret: + MOVW 100(R29), R1 + MOVW 104(R29), R2 + // Do the write. + MOVW R21, (R20) + RET + +flush: + // Save all general purpose registers since these could be + // clobbered by wbBufFlush and were not saved by the caller. + MOVW R20, 4(R29) // Also first argument to wbBufFlush + MOVW R21, 8(R29) // Also second argument to wbBufFlush + // R1 already saved + // R2 already saved + MOVW R3, 12(R29) + MOVW R4, 16(R29) + MOVW R5, 20(R29) + MOVW R6, 24(R29) + MOVW R7, 28(R29) + MOVW R8, 32(R29) + MOVW R9, 36(R29) + MOVW R10, 40(R29) + MOVW R11, 44(R29) + MOVW R12, 48(R29) + MOVW R13, 52(R29) + MOVW R14, 56(R29) + MOVW R15, 60(R29) + MOVW R16, 64(R29) + MOVW R17, 68(R29) + MOVW R18, 72(R29) + MOVW R19, 76(R29) + MOVW R20, 80(R29) + // R21 already saved + // R22 already saved. + MOVW R22, 84(R29) + // R23 is tmp register. + MOVW R24, 88(R29) + MOVW R25, 92(R29) + // R26 is reserved by kernel. + // R27 is reserved by kernel. + MOVW R28, 96(R29) + // R29 is SP. + // R30 is g. + // R31 is LR, which was saved by the prologue. + + // This takes arguments R20 and R21. + CALL runtime·wbBufFlush(SB) + + MOVW 4(R29), R20 + MOVW 8(R29), R21 + MOVW 12(R29), R3 + MOVW 16(R29), R4 + MOVW 20(R29), R5 + MOVW 24(R29), R6 + MOVW 28(R29), R7 + MOVW 32(R29), R8 + MOVW 36(R29), R9 + MOVW 40(R29), R10 + MOVW 44(R29), R11 + MOVW 48(R29), R12 + MOVW 52(R29), R13 + MOVW 56(R29), R14 + MOVW 60(R29), R15 + MOVW 64(R29), R16 + MOVW 68(R29), R17 + MOVW 72(R29), R18 + MOVW 76(R29), R19 + MOVW 80(R29), R20 + MOVW 84(R29), R22 + MOVW 88(R29), R24 + MOVW 92(R29), R25 + MOVW 96(R29), R28 + JMP ret |