mirror of
https://github.com/golang/go
synced 2024-11-19 12:54:45 -07:00
runtime: buffered write barrier for amd64p32
Updates #22460. Change-Id: I6656d478625e5e54aa2eaa38d99dfb0f71ea1fdd Reviewed-on: https://go-review.googlesource.com/92697 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
252f1170e5
commit
24dd83d7eb
@ -408,7 +408,7 @@ func Main(archInit func(*Arch)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch objabi.GOARCH {
|
switch objabi.GOARCH {
|
||||||
case "amd64", "386":
|
case "amd64", "amd64p32", "386":
|
||||||
default:
|
default:
|
||||||
// Other architectures don't support the buffered
|
// Other architectures don't support the buffered
|
||||||
// write barrier yet.
|
// write barrier yet.
|
||||||
|
@ -298,6 +298,9 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config
|
|||||||
// Returns clobber BP on nacl/386, so the write
|
// Returns clobber BP on nacl/386, so the write
|
||||||
// barrier does.
|
// barrier does.
|
||||||
opcodeTable[Op386LoweredWB].reg.clobbers |= 1 << 5 // BP
|
opcodeTable[Op386LoweredWB].reg.clobbers |= 1 << 5 // BP
|
||||||
|
|
||||||
|
// ... and SI on nacl/amd64.
|
||||||
|
opcodeTable[OpAMD64LoweredWB].reg.clobbers |= 1 << 6 // SI
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt.Flag_shared {
|
if ctxt.Flag_shared {
|
||||||
|
@ -567,7 +567,7 @@ func init() {
|
|||||||
|
|
||||||
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
|
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
|
||||||
// It saves all GP registers if necessary, but may clobber others.
|
// It saves all GP registers if necessary, but may clobber others.
|
||||||
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave ^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
|
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
|
||||||
|
|
||||||
// MOVQconvert converts between pointers and integers.
|
// MOVQconvert converts between pointers and integers.
|
||||||
// We have a special op for this so as to not confuse GC
|
// We have a special op for this so as to not confuse GC
|
||||||
|
@ -27,3 +27,5 @@ runtime/asm_amd64p32.s: [amd64p32] indexbytebody: function indexbytebody missing
|
|||||||
runtime/asm_amd64p32.s: [amd64p32] asmcgocall: RET without writing to 4-byte ret+8(FP)
|
runtime/asm_amd64p32.s: [amd64p32] asmcgocall: RET without writing to 4-byte ret+8(FP)
|
||||||
|
|
||||||
runtime/asm_amd64p32.s: [amd64p32] stackcheck: function stackcheck missing Go declaration
|
runtime/asm_amd64p32.s: [amd64p32] stackcheck: function stackcheck missing Go declaration
|
||||||
|
|
||||||
|
runtime/asm_ARCHSUFF.s: [GOARCH] gcWriteBarrier: function gcWriteBarrier missing Go declaration
|
||||||
|
@ -973,3 +973,84 @@ TEXT runtime·goexit(SB),NOSPLIT,$0-0
|
|||||||
TEXT ·checkASM(SB),NOSPLIT,$0-1
|
TEXT ·checkASM(SB),NOSPLIT,$0-1
|
||||||
MOVB $1, ret+0(FP)
|
MOVB $1, ret+0(FP)
|
||||||
RET
|
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 and SI. It does not clobber any other general-purpose registers,
|
||||||
|
// but may clobber others (e.g., SSE registers).
|
||||||
|
TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$88
|
||||||
|
// Save the registers clobbered by the fast path. This is slightly
|
||||||
|
// faster than having the caller spill these.
|
||||||
|
MOVQ R14, 72(SP)
|
||||||
|
MOVQ R13, 80(SP)
|
||||||
|
// TODO: Consider passing g.m.p in as an argument so they can be shared
|
||||||
|
// across a sequence of write barriers.
|
||||||
|
get_tls(R13)
|
||||||
|
MOVL g(R13), R13
|
||||||
|
MOVL g_m(R13), R13
|
||||||
|
MOVL m_p(R13), R13
|
||||||
|
MOVL (p_wbBuf+wbBuf_next)(R13), R14
|
||||||
|
// Increment wbBuf.next position.
|
||||||
|
LEAL 8(R14), R14
|
||||||
|
MOVL R14, (p_wbBuf+wbBuf_next)(R13)
|
||||||
|
CMPL R14, (p_wbBuf+wbBuf_end)(R13)
|
||||||
|
// Record the write.
|
||||||
|
MOVL AX, -8(R14) // Record value
|
||||||
|
MOVL (DI), R13 // TODO: This turns bad writes into bad reads.
|
||||||
|
MOVL R13, -4(R14) // Record *slot
|
||||||
|
// Is the buffer full? (flags set in CMPL above)
|
||||||
|
JEQ flush
|
||||||
|
ret:
|
||||||
|
MOVQ 72(SP), R14
|
||||||
|
MOVQ 80(SP), R13
|
||||||
|
// Do the write.
|
||||||
|
MOVL AX, (DI)
|
||||||
|
RET // Clobbers SI on NaCl
|
||||||
|
|
||||||
|
flush:
|
||||||
|
// Save all general purpose registers since these could be
|
||||||
|
// clobbered by wbBufFlush and were not saved by the caller.
|
||||||
|
// It is possible for wbBufFlush to clobber other registers
|
||||||
|
// (e.g., SSE registers), but the compiler takes care of saving
|
||||||
|
// those in the caller if necessary. This strikes a balance
|
||||||
|
// with registers that are likely to be used.
|
||||||
|
//
|
||||||
|
// We don't have type information for these, but all code under
|
||||||
|
// here is NOSPLIT, so nothing will observe these.
|
||||||
|
//
|
||||||
|
// TODO: We could strike a different balance; e.g., saving X0
|
||||||
|
// and not saving GP registers that are less likely to be used.
|
||||||
|
MOVL DI, 0(SP) // Also first argument to wbBufFlush
|
||||||
|
MOVL AX, 4(SP) // Also second argument to wbBufFlush
|
||||||
|
MOVQ BX, 8(SP)
|
||||||
|
MOVQ CX, 16(SP)
|
||||||
|
MOVQ DX, 24(SP)
|
||||||
|
// DI already saved
|
||||||
|
// SI is always clobbered on nacl
|
||||||
|
// BP is reserved on nacl
|
||||||
|
MOVQ R8, 32(SP)
|
||||||
|
MOVQ R9, 40(SP)
|
||||||
|
MOVQ R10, 48(SP)
|
||||||
|
MOVQ R11, 56(SP)
|
||||||
|
MOVQ R12, 64(SP)
|
||||||
|
// R13 already saved
|
||||||
|
// R14 already saved
|
||||||
|
// R15 is reserved on nacl
|
||||||
|
|
||||||
|
// This takes arguments DI and AX
|
||||||
|
CALL runtime·wbBufFlush(SB)
|
||||||
|
|
||||||
|
MOVL 0(SP), DI
|
||||||
|
MOVL 4(SP), AX
|
||||||
|
MOVQ 8(SP), BX
|
||||||
|
MOVQ 16(SP), CX
|
||||||
|
MOVQ 24(SP), DX
|
||||||
|
MOVQ 32(SP), R8
|
||||||
|
MOVQ 40(SP), R9
|
||||||
|
MOVQ 48(SP), R10
|
||||||
|
MOVQ 56(SP), R11
|
||||||
|
MOVQ 64(SP), R12
|
||||||
|
JMP ret
|
||||||
|
Loading…
Reference in New Issue
Block a user