mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: allow static init for unsafe.Pointer(&x) where x is global
This avoids both a write barrier and then dynamic initialization globals of the form var x something var xp = unsafe.Pointer(&x) Using static initialization avoids emitting a relocation for &x, which helps cgo. Fixes #9411. Change-Id: I0dbf480859cce6ab57ab805d1b8609c45b48f156 Reviewed-on: https://go-review.googlesource.com/11693 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
d6e6baa702
commit
9f90f31c3a
3 changed files with 24 additions and 4 deletions
|
|
@ -302,6 +302,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
|
||||||
orig := r
|
orig := r
|
||||||
r = r.Name.Defn.Right
|
r = r.Name.Defn.Right
|
||||||
|
|
||||||
|
for r.Op == OCONVNOP {
|
||||||
|
r = r.Left
|
||||||
|
}
|
||||||
|
|
||||||
switch r.Op {
|
switch r.Op {
|
||||||
case ONAME:
|
case ONAME:
|
||||||
if staticcopy(l, r, out) {
|
if staticcopy(l, r, out) {
|
||||||
|
|
@ -395,6 +399,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
|
||||||
func staticassign(l *Node, r *Node, out **NodeList) bool {
|
func staticassign(l *Node, r *Node, out **NodeList) bool {
|
||||||
var n1 Node
|
var n1 Node
|
||||||
|
|
||||||
|
for r.Op == OCONVNOP {
|
||||||
|
r = r.Left
|
||||||
|
}
|
||||||
|
|
||||||
switch r.Op {
|
switch r.Op {
|
||||||
//dump("not static", r);
|
//dump("not static", r);
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -2194,13 +2194,20 @@ func needwritebarrier(l *Node, r *Node) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// No write barrier for implicit or explicit zeroing.
|
// No write barrier for implicit zeroing.
|
||||||
if r == nil || iszero(r) {
|
if r == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// No write barrier for initialization to constant.
|
// Ignore no-op conversions when making decision.
|
||||||
if r.Op == OLITERAL {
|
// Ensures that xp = unsafe.Pointer(&x) is treated
|
||||||
|
// the same as xp = &x.
|
||||||
|
for r.Op == OCONVNOP {
|
||||||
|
r = r.Left
|
||||||
|
}
|
||||||
|
|
||||||
|
// No write barrier for zeroing or initialization to constant.
|
||||||
|
if iszero(r) || r.Op == OLITERAL {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
// Should be no init func in the assembly.
|
// Should be no init func in the assembly.
|
||||||
// All these initializations should be done at link time.
|
// All these initializations should be done at link time.
|
||||||
|
|
||||||
|
|
@ -284,3 +286,6 @@ type Mer interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Mer = (*T1)(nil)
|
var _ Mer = (*T1)(nil)
|
||||||
|
|
||||||
|
var Byte byte
|
||||||
|
var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue