]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: simplify bulkBarrierPreWrite
authorAustin Clements <austin@google.com>
Fri, 16 Feb 2018 22:45:21 +0000 (17:45 -0500)
committerAustin Clements <austin@google.com>
Wed, 21 Feb 2018 20:32:33 +0000 (20:32 +0000)
Currently, bulkBarrierPreWrite uses inheap to decide whether the
destination is in the heap or whether to check for stack or global
data. However, this isn't the best question to ask.

Instead, get the span directly and query its state. This lets us
directly determine whether this might be a global, or is stack memory,
or is heap memory.

At this point, inheap is no longer used in the hot path, so drop it
from the must-be-inlined list and substitute spanOf.

This will help in a circuitous way with #23862, since fixing that is
going to push inheap very slightly over the inline-able threshold on a
few platforms.

Change-Id: I5360fc1181183598502409f12979899e1e4d45f7
Reviewed-on: https://go-review.googlesource.com/95495
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
src/cmd/compile/internal/gc/inl_test.go
src/runtime/mbitmap.go

index 3e6da2ed7bbba3c5bb1da341e3f0e7a142b64037..a937c15432da2d672cf9c83b11c329811613acac 100644 (file)
@@ -78,10 +78,10 @@ func TestIntendedInlining(t *testing.T) {
                        "heapBits.morePointers",
                        "heapBits.next",
                        "heapBitsForAddr",
-                       "inheap",
                        "markBits.isMarked",
                        "muintptr.ptr",
                        "puintptr.ptr",
+                       "spanOf",
                        "spanOfUnchecked",
                        "(*gcWork).putFast",
                        "(*gcWork).tryGetFast",
index 0027bc9c057c72a864d8ba764a393ab0b2eb2ae3..3dc22e8458e8eab96d13c2053528f531d5d691d7 100644 (file)
@@ -574,13 +574,7 @@ func bulkBarrierPreWrite(dst, src, size uintptr) {
        if !writeBarrier.needed {
                return
        }
-       if !inheap(dst) {
-               gp := getg().m.curg
-               if gp != nil && gp.stack.lo <= dst && dst < gp.stack.hi {
-                       // Destination is our own stack. No need for barriers.
-                       return
-               }
-
+       if s := spanOf(dst); s == nil {
                // If dst is a global, use the data or BSS bitmaps to
                // execute write barriers.
                for _, datap := range activeModules() {
@@ -596,6 +590,14 @@ func bulkBarrierPreWrite(dst, src, size uintptr) {
                        }
                }
                return
+       } else if s.state != _MSpanInUse || dst < s.base() || s.limit <= dst {
+               // dst was heap memory at some point, but isn't now.
+               // It can't be a global. It must be either our stack,
+               // or in the case of direct channel sends, it could be
+               // another stack. Either way, no need for barriers.
+               // This will also catch if dst is in a freed span,
+               // though that should never have.
+               return
        }
 
        buf := &getg().m.p.ptr().wbBuf