diff options
| author | Keith Randall <khr@golang.org> | 2022-11-01 16:46:43 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2023-02-24 00:21:13 +0000 |
| commit | 21d82e6ac80fc2aea1eac9c8eec9afdd79cb5bdd (patch) | |
| tree | 293b975ed4dc782a0d68ab64dc6167b6d6486066 /src/runtime/asm_arm64.s | |
| parent | f684f3dc434f9199ceee175c07d28e8b2b0f28dc (diff) | |
| download | go-21d82e6ac80fc2aea1eac9c8eec9afdd79cb5bdd.tar.xz | |
cmd/compile: batch write barrier calls
Have the write barrier call return a pointer to a buffer into which
the generated code records pointers that need write barrier treatment.
Change-Id: I7871764298e0aa1513de417010c8d46b296b199e
Reviewed-on: https://go-review.googlesource.com/c/go/+/447781
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Bypass: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/runtime/asm_arm64.s')
| -rw-r--r-- | src/runtime/asm_arm64.s | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index e8399712de..d0dd73cc00 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -1188,37 +1188,33 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1 MOVB R3, ret+0(FP) RET -// gcWriteBarrier performs a heap pointer write and informs the GC. +// gcWriteBarrier informs the GC about heap pointer writes. // -// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments: -// - R2 is the destination of the write -// - R3 is the value being written at R2 +// gcWriteBarrier does NOT follow the Go ABI. It accepts the +// number of bytes of buffer needed in R25, and returns a pointer +// to the buffer space in R25. // It clobbers condition codes. // It does not clobber any general-purpose registers except R27, // but may clobber others (e.g., floating point registers) // The act of CALLing gcWriteBarrier will clobber R30 (LR). -// -// Defined as ABIInternal since the compiler generates ABIInternal -// calls to it directly and it does not use the stack-based Go ABI. -TEXT runtime·gcWriteBarrier<ABIInternal>(SB),NOSPLIT,$200 +TEXT gcWriteBarrier<>(SB),NOSPLIT,$200 // Save the registers clobbered by the fast path. STP (R0, R1), 184(RSP) retry: MOVD g_m(g), R0 MOVD m_p(R0), R0 - MOVD (p_wbBuf+wbBuf_next)(R0), R1 - MOVD (p_wbBuf+wbBuf_end)(R0), R27 + MOVD (p_wbBuf+wbBuf_next)(R0), R1 + MOVD (p_wbBuf+wbBuf_end)(R0), R27 // Increment wbBuf.next position. - ADD $16, R1 + ADD R25, R1 // Is the buffer full? CMP R27, R1 BHI flush // Commit to the larger buffer. MOVD R1, (p_wbBuf+wbBuf_next)(R0) - // Record the write. - MOVD R3, -16(R1) // Record value - MOVD (R2), R0 // TODO: This turns bad writes into bad reads. - MOVD R0, -8(R1) // Record *slot + // Make return value (the original next position) + SUB R25, R1, R25 + // Restore registers. LDP 184(RSP), (R0, R1) RET @@ -1259,6 +1255,31 @@ flush: LDP 21*8(RSP), (R25, R26) JMP retry +TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0 + MOVD $8, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0 + MOVD $16, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0 + MOVD $24, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0 + MOVD $32, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0 + MOVD $40, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0 + MOVD $48, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0 + MOVD $56, R25 + JMP gcWriteBarrier<>(SB) +TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0 + MOVD $64, R25 + JMP gcWriteBarrier<>(SB) + DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large" GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below |
