mirror of
https://github.com/golang/go.git
synced 2025-05-20 14:53:23 +00:00
cmd/compile: mark architecture-specific unsafe points
Introduce a mechanism for marking architecture-specific Ops unsafe. And mark ones that use REGTMP on ARM64, as for async preemption we will be using REGTMP as a temporary register in the injected call. Change-Id: I8ff22e87d8f9cb10d02a2f0af7c12ad6d7d58f54 Reviewed-on: https://go-review.googlesource.com/c/go/+/203459 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
0f992b9948
commit
4a7ed1fab7
@ -639,6 +639,15 @@ func (lv *Liveness) markUnsafePoints() {
|
|||||||
|
|
||||||
lv.unsafePoints = bvalloc(int32(lv.f.NumValues()))
|
lv.unsafePoints = bvalloc(int32(lv.f.NumValues()))
|
||||||
|
|
||||||
|
// Mark architecture-specific unsafe pointes.
|
||||||
|
for _, b := range lv.f.Blocks {
|
||||||
|
for _, v := range b.Values {
|
||||||
|
if v.Op.UnsafePoint() {
|
||||||
|
lv.unsafePoints.Set(int32(v.ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mark write barrier unsafe points.
|
// Mark write barrier unsafe points.
|
||||||
for _, wbBlock := range lv.f.WBLoads {
|
for _, wbBlock := range lv.f.WBLoads {
|
||||||
if wbBlock.Kind == ssa.BlockPlain && len(wbBlock.Values) == 0 {
|
if wbBlock.Kind == ssa.BlockPlain && len(wbBlock.Values) == 0 {
|
||||||
|
@ -620,8 +620,8 @@ func init() {
|
|||||||
// LDAXR (Rarg0), Rout
|
// LDAXR (Rarg0), Rout
|
||||||
// STLXR Rarg1, (Rarg0), Rtmp
|
// STLXR Rarg1, (Rarg0), Rtmp
|
||||||
// CBNZ Rtmp, -2(PC)
|
// CBNZ Rtmp, -2(PC)
|
||||||
{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
|
|
||||||
// atomic add.
|
// atomic add.
|
||||||
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
||||||
@ -629,8 +629,8 @@ func init() {
|
|||||||
// ADD Rarg1, Rout
|
// ADD Rarg1, Rout
|
||||||
// STLXR Rout, (Rarg0), Rtmp
|
// STLXR Rout, (Rarg0), Rtmp
|
||||||
// CBNZ Rtmp, -3(PC)
|
// CBNZ Rtmp, -3(PC)
|
||||||
{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
|
|
||||||
// atomic add variant.
|
// atomic add variant.
|
||||||
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
||||||
@ -653,8 +653,8 @@ func init() {
|
|||||||
// STLXR Rarg2, (Rarg0), Rtmp
|
// STLXR Rarg2, (Rarg0), Rtmp
|
||||||
// CBNZ Rtmp, -4(PC)
|
// CBNZ Rtmp, -4(PC)
|
||||||
// CSET EQ, Rout
|
// CSET EQ, Rout
|
||||||
{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
|
|
||||||
// atomic and/or.
|
// atomic and/or.
|
||||||
// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
||||||
@ -662,8 +662,8 @@ func init() {
|
|||||||
// AND/OR Rarg1, Rout
|
// AND/OR Rarg1, Rout
|
||||||
// STLXRB Rout, (Rarg0), Rtmp
|
// STLXRB Rout, (Rarg0), Rtmp
|
||||||
// CBNZ Rtmp, -3(PC)
|
// CBNZ Rtmp, -3(PC)
|
||||||
{name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
{name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true},
|
{name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
|
||||||
|
|
||||||
// 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,
|
// It saves all GP registers if necessary,
|
||||||
|
@ -63,6 +63,7 @@ type opData struct {
|
|||||||
usesScratch bool // this op requires scratch memory space
|
usesScratch bool // this op requires scratch memory space
|
||||||
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
|
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
|
||||||
zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
|
zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
|
||||||
|
unsafePoint bool // this op is an unsafe point, i.e. not safe for async preemption
|
||||||
symEffect string // effect this op has on symbol in aux
|
symEffect string // effect this op has on symbol in aux
|
||||||
scale uint8 // amd64/386 indexed load scale
|
scale uint8 // amd64/386 indexed load scale
|
||||||
}
|
}
|
||||||
@ -325,6 +326,9 @@ func genOp() {
|
|||||||
if v.zeroWidth {
|
if v.zeroWidth {
|
||||||
fmt.Fprintln(w, "zeroWidth: true,")
|
fmt.Fprintln(w, "zeroWidth: true,")
|
||||||
}
|
}
|
||||||
|
if v.unsafePoint {
|
||||||
|
fmt.Fprintln(w, "unsafePoint: true,")
|
||||||
|
}
|
||||||
needEffect := strings.HasPrefix(v.aux, "Sym")
|
needEffect := strings.HasPrefix(v.aux, "Sym")
|
||||||
if v.symEffect != "" {
|
if v.symEffect != "" {
|
||||||
if !needEffect {
|
if !needEffect {
|
||||||
@ -401,6 +405,7 @@ func genOp() {
|
|||||||
|
|
||||||
fmt.Fprintln(w, "func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }")
|
fmt.Fprintln(w, "func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }")
|
||||||
fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }")
|
fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }")
|
||||||
|
fmt.Fprintln(w, "func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }")
|
||||||
|
|
||||||
// generate registers
|
// generate registers
|
||||||
for _, a := range archs {
|
for _, a := range archs {
|
||||||
|
@ -36,6 +36,7 @@ type opInfo struct {
|
|||||||
usesScratch bool // this op requires scratch memory space
|
usesScratch bool // this op requires scratch memory space
|
||||||
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
|
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
|
||||||
zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
|
zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
|
||||||
|
unsafePoint bool // this op is an unsafe point, i.e. not safe for async preemption
|
||||||
symEffect SymEffect // effect this op has on symbol in aux
|
symEffect SymEffect // effect this op has on symbol in aux
|
||||||
scale uint8 // amd64/386 indexed load scale
|
scale uint8 // amd64/386 indexed load scale
|
||||||
}
|
}
|
||||||
|
@ -18948,6 +18948,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
resultNotInArgs: true,
|
resultNotInArgs: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||||
@ -18964,6 +18965,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
resultNotInArgs: true,
|
resultNotInArgs: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||||
@ -18980,6 +18982,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
resultNotInArgs: true,
|
resultNotInArgs: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||||
@ -18996,6 +18999,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
resultNotInArgs: true,
|
resultNotInArgs: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||||
@ -19045,6 +19049,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
clobberFlags: true,
|
clobberFlags: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||||
@ -19063,6 +19068,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
clobberFlags: true,
|
clobberFlags: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||||
@ -19080,6 +19086,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
resultNotInArgs: true,
|
resultNotInArgs: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
asm: arm64.AAND,
|
asm: arm64.AAND,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -19097,6 +19104,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
resultNotInArgs: true,
|
resultNotInArgs: true,
|
||||||
faultOnNilArg0: true,
|
faultOnNilArg0: true,
|
||||||
hasSideEffects: true,
|
hasSideEffects: true,
|
||||||
|
unsafePoint: true,
|
||||||
asm: arm64.AORR,
|
asm: arm64.AORR,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
@ -31564,6 +31572,7 @@ func (o Op) String() string { return opcodeTable[o].name }
|
|||||||
func (o Op) UsesScratch() bool { return opcodeTable[o].usesScratch }
|
func (o Op) UsesScratch() bool { return opcodeTable[o].usesScratch }
|
||||||
func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }
|
func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }
|
||||||
func (o Op) IsCall() bool { return opcodeTable[o].call }
|
func (o Op) IsCall() bool { return opcodeTable[o].call }
|
||||||
|
func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }
|
||||||
|
|
||||||
var registers386 = [...]Register{
|
var registers386 = [...]Register{
|
||||||
{0, x86.REG_AX, 0, "AX"},
|
{0, x86.REG_AX, 0, "AX"},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user