aboutsummaryrefslogtreecommitdiff
path: root/test/nowritebarrier.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-10-10 16:46:28 -0400
committerAustin Clements <austin@google.com>2016-10-15 17:58:11 +0000
commita9e6cebde21875379ccc05d680b3c3a78adbf089 (patch)
treee569ea3996210899df8e65f8d6efdd26ca0a04a2 /test/nowritebarrier.go
parent6347367be36df608cce84beb097378f8654dd208 (diff)
downloadgo-a9e6cebde21875379ccc05d680b3c3a78adbf089.tar.gz
go-a9e6cebde21875379ccc05d680b3c3a78adbf089.zip
cmd/compile, runtime: add go:yeswritebarrierrec pragma
This pragma cancels the effect of go:nowritebarrierrec. This is useful in the scheduler because there are places where we enter a function without a valid P (and hence cannot have write barriers), but then obtain a P. This allows us to annotate the function with go:nowritebarrierrec and split out the part after we've obtained a P into a go:yeswritebarrierrec function. Change-Id: Ic8ce4b6d3c074a1ecd8280ad90eaf39f0ffbcc2a Reviewed-on: https://go-review.googlesource.com/30938 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'test/nowritebarrier.go')
-rw-r--r--test/nowritebarrier.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/test/nowritebarrier.go b/test/nowritebarrier.go
new file mode 100644
index 0000000000..23dce753b0
--- /dev/null
+++ b/test/nowritebarrier.go
@@ -0,0 +1,78 @@
+// errorcheck -+
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test go:nowritebarrier and related directives.
+
+package p
+
+type t struct {
+ f *t
+}
+
+var x t
+var y *t
+
+//go:nowritebarrier
+func a1() {
+ x.f = y // ERROR "write barrier prohibited"
+ a2() // no error
+}
+
+//go:noinline
+func a2() {
+ x.f = y
+}
+
+//go:nowritebarrierrec
+func b1() {
+ b2()
+}
+
+//go:noinline
+func b2() {
+ x.f = y // ERROR "write barrier prohibited by caller"
+}
+
+// Test recursive cycles through nowritebarrierrec and yeswritebarrierrec.
+
+//go:nowritebarrierrec
+func c1() {
+ c2()
+}
+
+//go:yeswritebarrierrec
+func c2() {
+ c3()
+}
+
+func c3() {
+ x.f = y
+ c4()
+}
+
+//go:nowritebarrierrec
+func c4() {
+ c2()
+}
+
+//go:nowritebarrierrec
+func d1() {
+ d2()
+}
+
+func d2() {
+ d3()
+}
+
+func d3() {
+ x.f = y // ERROR "write barrier prohibited by caller"
+ d4()
+}
+
+//go:yeswritebarrierrec
+func d4() {
+ d2()
+}