mirror of
https://github.com/golang/go
synced 2024-11-19 22:14:43 -07:00
b78b54ff83
Currently copy and append for types containing only scalars and notinheap pointers still get compiled to have write barriers, even though those write barriers are unnecessary. Fix these to use HasHeapPointer instead of just Haspointer so that they elide write barriers when possible. This fixes the unnecessary write barrier in runtime.recordspan when it grows the h.allspans slice. This is important because recordspan gets called (*very* indirectly) from (*gcWork).tryGet, which is go:nowritebarrierrec. Unfortunately, the compiler's analysis has no hope of seeing this because it goes through the indirect call fixalloc.first, but I saw it happen. Change-Id: Ieba3abc555a45f573705eab780debcfe5c4f5dd1 Reviewed-on: https://go-review.googlesource.com/73413 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
57 lines
936 B
Go
57 lines
936 B
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
|
|
y [1024]byte // Prevent write decomposition
|
|
}
|
|
|
|
type t2 struct {
|
|
x *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"
|
|
}
|
|
|
|
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"
|
|
}
|