go/test/notinheap3.go
Austin Clements 3a446d8652 cmd/compile: []T where T is go:notinheap does not need write barriers
Currently, assigning a []T where T is a go:notinheap type generates an
unnecessary write barrier for storing the slice pointer.

This fixes this by teaching HasHeapPointer that this type does not
have a heap pointer, and tweaking the lowering of slice assignments so
the pointer store retains the correct type rather than simply lowering
it to a *uint8 store.

Change-Id: I8bf7c66e64a7fefdd14f2bd0de8a5a3596340bab
Reviewed-on: https://go-review.googlesource.com/76027
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-11-06 21:07:57 +00:00

60 lines
1 KiB
Go

// errorcheck -+ -0 -l -d=wb
// 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 write barrier elimination for notinheap.
package p
type t1 struct {
x *nih
s []nih
y [1024]byte // Prevent write decomposition
}
type t2 struct {
x *ih
s []ih
y [1024]byte
}
//go:notinheap
type nih struct {
x uintptr
}
type ih struct { // In-heap type
x uintptr
}
var (
v1 t1
v2 t2
v1s []t1
v2s []t2
)
func f() {
// Test direct writes
v1.x = nil // no barrier
v2.x = nil // ERROR "write barrier"
v1.s = []nih(nil) // no barrier
v2.s = []ih(nil) // ERROR "write barrier"
}
func g() {
// Test aggregate writes
v1 = t1{x: nil} // no barrier
v2 = t2{x: nil} // ERROR "write barrier"
}
func h() {
// Test copies and appends.
copy(v1s, v1s[1:]) // no barrier
copy(v2s, v2s[1:]) // ERROR "write barrier"
_ = append(v1s, v1s...) // no barrier
_ = append(v2s, v2s...) // ERROR "write barrier"
}