Skip to content
This repository has been archived by the owner on May 2, 2018. It is now read-only.

Commit

Permalink
cmd/compile: allow static init for unsafe.Pointer(&x) where x is global
Browse files Browse the repository at this point in the history
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 <[email protected]>
Run-TryBot: Russ Cox <[email protected]>
  • Loading branch information
rsc committed Jul 7, 2015
1 parent d6e6baa commit 9f90f31
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/cmd/compile/internal/gc/sinit.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
orig := r
r = r.Name.Defn.Right

for r.Op == OCONVNOP {
r = r.Left
}

switch r.Op {
case ONAME:
if staticcopy(l, r, out) {
Expand Down Expand Up @@ -395,6 +399,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
func staticassign(l *Node, r *Node, out **NodeList) bool {
var n1 Node

for r.Op == OCONVNOP {
r = r.Left
}

switch r.Op {
//dump("not static", r);
default:
Expand Down
15 changes: 11 additions & 4 deletions src/cmd/compile/internal/gc/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -2194,13 +2194,20 @@ func needwritebarrier(l *Node, r *Node) bool {
return false
}

// No write barrier for implicit or explicit zeroing.
if r == nil || iszero(r) {
// No write barrier for implicit zeroing.
if r == nil {
return false
}

// No write barrier for initialization to constant.
if r.Op == OLITERAL {
// Ignore no-op conversions when making decision.
// 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
}

Expand Down
5 changes: 5 additions & 0 deletions test/sinit.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

package p

import "unsafe"

// Should be no init func in the assembly.
// All these initializations should be done at link time.

Expand Down Expand Up @@ -284,3 +286,6 @@ type Mer interface {
}

var _ Mer = (*T1)(nil)

var Byte byte
var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)

0 comments on commit 9f90f31

Please sign in to comment.