]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add GODEBUG for stack barriers at every frame
authorAustin Clements <austin@google.com>
Wed, 26 Aug 2015 17:54:26 +0000 (13:54 -0400)
committerAustin Clements <austin@google.com>
Sun, 30 Aug 2015 16:06:55 +0000 (16:06 +0000)
Currently enabling the debugging mode where stack barriers are
installed at every frame requires recompiling the runtime. However,
this is potentially useful for field debugging and for runtime tests,
so make this mode a GODEBUG.

Updates #12238.

Change-Id: I6fb128f598b19568ae723a612e099c0ed96917f5
Reviewed-on: https://go-review.googlesource.com/13947
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/extern.go
src/runtime/mgc.go
src/runtime/mgcmark.go
src/runtime/runtime1.go

index d3463627731351447693ef3cf1fa4e55eca111e9..cdb66ba24e7429be82d6ed0daeee72fbaf72040d 100644 (file)
@@ -47,6 +47,9 @@ It is a comma-separated list of name=val pairs setting these named variables:
        that allow the garbage collector to avoid repeating a stack scan during the
        mark termination phase.
 
+       gcstackbarrierall: setting gcstackbarrierall=1 installs stack barriers
+       in every stack frame, rather than in exponentially-spaced frames.
+
        gcstoptheworld: setting gcstoptheworld=1 disables concurrent garbage collection,
        making every garbage collection a stop-the-world event. Setting gcstoptheworld=2
        also disables concurrent sweeping after the garbage collection finishes.
index f7fd4e51d5fec859f6ab27100b8065665cfc03bc..82b12b6c0952757f30a8b35cae929cae53120321 100644 (file)
@@ -133,18 +133,7 @@ const (
        _RootFlushCaches = 4
        _RootCount       = 5
 
-       // firstStackBarrierOffset is the approximate byte offset at
-       // which to place the first stack barrier from the current SP.
-       // This is a lower bound on how much stack will have to be
-       // re-scanned during mark termination. Subsequent barriers are
-       // placed at firstStackBarrierOffset * 2^n offsets.
-       //
-       // For debugging, this can be set to 0, which will install a
-       // stack barrier at every frame. If you do this, you may also
-       // have to raise _StackMin, since the stack barrier
-       // bookkeeping will use a large amount of each stack.
-       firstStackBarrierOffset = 1024
-       debugStackBarrier       = false
+       debugStackBarrier = false
 
        // sweepMinHeapDistance is a lower bound on the heap distance
        // (in bytes) reserved for concurrent sweeping between GC
@@ -152,6 +141,18 @@ const (
        sweepMinHeapDistance = 1024 * 1024
 )
 
+// firstStackBarrierOffset is the approximate byte offset at
+// which to place the first stack barrier from the current SP.
+// This is a lower bound on how much stack will have to be
+// re-scanned during mark termination. Subsequent barriers are
+// placed at firstStackBarrierOffset * 2^n offsets.
+//
+// For debugging, this can be set to 0, which will install a
+// stack barrier at every frame. If you do this, you may also
+// have to raise _StackMin, since the stack barrier
+// bookkeeping will use a large amount of each stack.
+var firstStackBarrierOffset = 1024
+
 // heapminimum is the minimum heap size at which to trigger GC.
 // For small heaps, this overrides the usual GOGC*live set rule.
 //
index 650d03862e84ccf8855962f0942afd2e27bc75c2..44f951269bb4e56eb835145be52520a16327514c 100644 (file)
@@ -341,7 +341,7 @@ func scanstack(gp *g) {
        switch gcphase {
        case _GCscan:
                // Install stack barriers during stack scan.
-               barrierOffset = firstStackBarrierOffset
+               barrierOffset = uintptr(firstStackBarrierOffset)
                nextBarrier = sp + barrierOffset
 
                if debug.gcstackbarrieroff > 0 {
index a50e5b618cfae4c7c19963e9eba3ed3af47e76d7..134c999088a221f66298cc62dc8ba48c0fe721ed 100644 (file)
@@ -310,6 +310,7 @@ var debug struct {
        gcpacertrace      int32
        gcshrinkstackoff  int32
        gcstackbarrieroff int32
+       gcstackbarrierall int32
        gcstoptheworld    int32
        gctrace           int32
        invalidptr        int32
@@ -327,6 +328,7 @@ var dbgvars = []dbgVar{
        {"gcpacertrace", &debug.gcpacertrace},
        {"gcshrinkstackoff", &debug.gcshrinkstackoff},
        {"gcstackbarrieroff", &debug.gcstackbarrieroff},
+       {"gcstackbarrierall", &debug.gcstackbarrierall},
        {"gcstoptheworld", &debug.gcstoptheworld},
        {"gctrace", &debug.gctrace},
        {"invalidptr", &debug.invalidptr},
@@ -382,6 +384,10 @@ func parsedebugvars() {
        if islibrary || isarchive {
                traceback_cache |= 1
        }
+
+       if debug.gcstackbarrierall > 0 {
+               firstStackBarrierOffset = 0
+       }
 }
 
 // Poor mans 64-bit division.