]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: use 32-bit load to read writebarrier
authorDavid Chase <drchase@google.com>
Sun, 28 Feb 2016 16:15:22 +0000 (11:15 -0500)
committerDavid Chase <drchase@google.com>
Sun, 28 Feb 2016 22:29:23 +0000 (22:29 +0000)
Avoid targeting a partial register with load;
ensure source of load (writebarrier) is aligned.

Better yet would be "CMPB $1,writebarrier" but that requires
wrestling with flagalloc (mem operand complicates moving
instruction around).

Didn't see a change in time for
   benchcmd -n 10 Build go build net/http

Verified that we clean the code up properly:
   0x20a8 <main.main+104>: mov    0xc30a2(%rip),%eax
                            # 0xc5150 <runtime.writeBarrier>
   0x20ae <main.main+110>: test   %al,%al

Change-Id: Id5fb8c260eaec27bd727cb0ae1476c60343b0986
Reviewed-on: https://go-review.googlesource.com/19998
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/ssa.go
src/runtime/mgc.go

index 98478061108a9a91468bb0c63200c5365ea4508f..8e68c20fb48196822c10ddad8e39735add362538 100644 (file)
@@ -2718,9 +2718,11 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32) {
        bEnd := s.f.NewBlock(ssa.BlockPlain)
 
        aux := &ssa.ExternSymbol{Types[TBOOL], syslook("writeBarrier", 0).Sym}
-       flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TBOOL]), aux, s.sb)
+       flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
        // TODO: select the .enabled field.  It is currently first, so not needed for now.
-       flag := s.newValue2(ssa.OpLoad, Types[TBOOL], flagaddr, s.mem())
+       // Load word, test byte, avoiding partial register write from load byte.
+       flag := s.newValue2(ssa.OpLoad, Types[TUINT32], flagaddr, s.mem())
+       flag = s.newValue1(ssa.OpTrunc64to8, Types[TBOOL], flag)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.Likely = ssa.BranchUnlikely
@@ -2761,9 +2763,11 @@ func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line int32) {
        bEnd := s.f.NewBlock(ssa.BlockPlain)
 
        aux := &ssa.ExternSymbol{Types[TBOOL], syslook("writeBarrier", 0).Sym}
-       flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TBOOL]), aux, s.sb)
+       flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
        // TODO: select the .enabled field.  It is currently first, so not needed for now.
-       flag := s.newValue2(ssa.OpLoad, Types[TBOOL], flagaddr, s.mem())
+       // Load word, test byte, avoiding partial register write from load byte.
+       flag := s.newValue2(ssa.OpLoad, Types[TUINT32], flagaddr, s.mem())
+       flag = s.newValue1(ssa.OpTrunc64to8, Types[TBOOL], flag)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.Likely = ssa.BranchUnlikely
index 94301c6dc7f0deb7aa91095dbeb367e9c432a55c..102d44160e6c881c6ff025c7cce53655e7eae4c9 100644 (file)
@@ -216,9 +216,10 @@ var gcphase uint32
 // The compiler knows about this variable.
 // If you change it, you must change the compiler too.
 var writeBarrier struct {
-       enabled bool // compiler emits a check of this before calling write barrier
-       needed  bool // whether we need a write barrier for current GC phase
-       cgo     bool // whether we need a write barrier for a cgo check
+       enabled bool   // compiler emits a check of this before calling write barrier
+       needed  bool   // whether we need a write barrier for current GC phase
+       cgo     bool   // whether we need a write barrier for a cgo check
+       alignme uint64 // guarantee alignment so that compiler can use a 32 or 64-bit load
 }
 
 // gcBlackenEnabled is 1 if mutator assists and background mark