]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: eliminate write barriers from gentraceback
authorAustin Clements <austin@google.com>
Tue, 17 Nov 2015 22:14:32 +0000 (17:14 -0500)
committerAustin Clements <austin@google.com>
Thu, 19 Nov 2015 21:17:04 +0000 (21:17 +0000)
gentraceback is used in many contexts where write barriers are
disallowed. This currently works because the only write barrier is in
assigning frame.argmap in setArgInfo and in practice frame is always
on the stack, so this write barrier is a no-op.

However, we can easily eliminate this write barrier, which will let us
statically disallow write barriers (using go:nowritebarrierrec
annotations) in many more situations. As a bonus, this makes the code
a little more idiomatic.

Updates #10600.

Change-Id: I45ba5cece83697ff79f8537ee6e43eadf1c18c6d
Reviewed-on: https://go-review.googlesource.com/17003
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
src/runtime/traceback.go

index b636f58eedbe780e9f30648ef2b929423b8fbdd9..8d1b75827148df98c2ef1eab0c0dce4a8a063610 100644 (file)
@@ -106,7 +106,7 @@ func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v uns
                        }
                        frame.fn = f
                        frame.argp = uintptr(deferArgs(d))
-                       setArgInfo(&frame, f, true)
+                       frame.arglen, frame.argmap = getArgInfo(&frame, f, true)
                }
                frame.continpc = frame.pc
                if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) {
@@ -328,7 +328,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                // metadata recorded by f's caller.
                if callback != nil || printing {
                        frame.argp = frame.fp + sys.MinFrameSize
-                       setArgInfo(&frame, f, callback != nil)
+                       frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil)
                }
 
                // Determine frame's 'continuation PC', where it can continue.
@@ -519,8 +519,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
        return n
 }
 
-func setArgInfo(frame *stkframe, f *_func, needArgMap bool) {
-       frame.arglen = uintptr(f.args)
+func getArgInfo(frame *stkframe, f *_func, needArgMap bool) (arglen uintptr, argmap *bitvector) {
+       arglen = uintptr(f.args)
        if needArgMap && f.args == _ArgsSizeUnknown {
                // Extract argument bitmaps for reflect stubs from the calls they made to reflect.
                switch funcname(f) {
@@ -532,10 +532,11 @@ func setArgInfo(frame *stkframe, f *_func, needArgMap bool) {
                                throw("reflect mismatch")
                        }
                        bv := (*bitvector)(unsafe.Pointer(fn[1]))
-                       frame.arglen = uintptr(bv.n * sys.PtrSize)
-                       frame.argmap = bv
+                       arglen = uintptr(bv.n * sys.PtrSize)
+                       argmap = bv
                }
        }
+       return
 }
 
 func printcreatedby(gp *g) {