aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDave Cheney <dave@cheney.net>2016-08-29 09:44:50 +1000
committerDave Cheney <dave@cheney.net>2016-08-30 08:08:37 +0000
commitadb1e67f02fa58b13d1baf60c84556f375f6ceeb (patch)
tree7c83bbed61cd257e0f56eb4260c064e328d0284f /src
parentb6e3a98cf3a7acb3d5c1431eb04e9c3edad6c6ed (diff)
downloadgo-adb1e67f02fa58b13d1baf60c84556f375f6ceeb.tar.xz
reflect: avoid zeroing memory that will be overwritten
Avoid new'ing memory that will be overwritten by assignment. name old time/op new time/op delta Call-4 160ns ± 4% 155ns ± 2% -3.19% (p=0.003 n=10+10) FieldByName1-4 94.5ns ± 2% 95.2ns ± 1% +0.65% (p=0.026 n=9+9) FieldByName2-4 3.09µs ± 4% 3.13µs ± 2% ~ (p=0.165 n=10+10) FieldByName3-4 19.8µs ± 1% 19.9µs ± 1% ~ (p=0.395 n=10+8) InterfaceBig-4 11.6ns ± 0% 11.7ns ± 0% +0.86% (p=0.000 n=8+9) InterfaceSmall-4 11.7ns ± 0% 11.7ns ± 0% ~ (all samples are equal) New-4 26.6ns ± 0% 26.4ns ± 0% -0.64% (p=0.000 n=10+9) name old alloc/op new alloc/op delta Call-4 0.00B ±NaN% 0.00B ±NaN% ~ (all samples are equal) name old allocs/op new allocs/op delta Call-4 0.00 ±NaN% 0.00 ±NaN% ~ (all samples are equal) Change-Id: I12c85d4e65245598669dd6f66beb0744ec9b9d6d Reviewed-on: https://go-review.googlesource.com/28011 Run-TryBot: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/reflect/type.go47
1 files changed, 22 insertions, 25 deletions
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 94c5d020c6..98cc9ceded 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -1456,25 +1456,24 @@ func (t *rtype) ptrTo() *rtype {
// Create a new ptrType starting with the description
// of an *unsafe.Pointer.
- p = new(ptrType)
var iptr interface{} = (*unsafe.Pointer)(nil)
prototype := *(**ptrType)(unsafe.Pointer(&iptr))
- *p = *prototype
+ pp := *prototype
- p.str = resolveReflectName(newName(s, "", "", false))
+ pp.str = resolveReflectName(newName(s, "", "", false))
// For the type structures linked into the binary, the
// compiler provides a good hash of the string.
// Create a good hash for the new string by using
// the FNV-1 hash's mixing function to combine the
// old hash and the new "*".
- p.hash = fnv1(t.hash, '*')
+ pp.hash = fnv1(t.hash, '*')
- p.elem = t
+ pp.elem = t
- ptrMap.m[t] = p
+ ptrMap.m[t] = &pp
ptrMap.Unlock()
- return &p.rtype
+ return &pp.rtype
}
// fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
@@ -1852,8 +1851,7 @@ func ChanOf(dir ChanDir, t Type) Type {
// Make a channel type.
var ichan interface{} = (chan unsafe.Pointer)(nil)
prototype := *(**chanType)(unsafe.Pointer(&ichan))
- ch := new(chanType)
- *ch = *prototype
+ ch := *prototype
ch.tflag = 0
ch.dir = uintptr(dir)
ch.str = resolveReflectName(newName(s, "", "", false))
@@ -1896,8 +1894,7 @@ func MapOf(key, elem Type) Type {
// Make a map type.
var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
- mt := new(mapType)
- *mt = **(**mapType)(unsafe.Pointer(&imap))
+ mt := **(**mapType)(unsafe.Pointer(&imap))
mt.str = resolveReflectName(newName(s, "", "", false))
mt.tflag = 0
mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
@@ -2248,15 +2245,16 @@ func bucketOf(ktyp, etyp *rtype) *rtype {
}
}
- b := new(rtype)
- b.align = ptrSize
+ b := &rtype{
+ align: ptrSize,
+ size: size,
+ kind: kind,
+ ptrdata: ptrdata,
+ gcdata: gcdata,
+ }
if overflowPad > 0 {
b.align = 8
}
- b.size = size
- b.ptrdata = ptrdata
- b.kind = kind
- b.gcdata = gcdata
s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
b.str = resolveReflectName(newName(s, "", "", false))
return b
@@ -2285,8 +2283,7 @@ func SliceOf(t Type) Type {
// Make a slice type.
var islice interface{} = ([]unsafe.Pointer)(nil)
prototype := *(**sliceType)(unsafe.Pointer(&islice))
- slice := new(sliceType)
- *slice = *prototype
+ slice := *prototype
slice.tflag = 0
slice.str = resolveReflectName(newName(s, "", "", false))
slice.hash = fnv1(typ.hash, '[')
@@ -2830,8 +2827,7 @@ func ArrayOf(count int, elem Type) Type {
// Make an array type.
var iarray interface{} = [1]unsafe.Pointer{}
prototype := *(**arrayType)(unsafe.Pointer(&iarray))
- array := new(arrayType)
- *array = *prototype
+ array := *prototype
array.str = resolveReflectName(newName(s, "", "", false))
array.hash = fnv1(typ.hash, '[')
for n := uint32(count); n > 0; n >>= 8 {
@@ -3071,13 +3067,14 @@ func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uin
offset += -offset & (ptrSize - 1)
// build dummy rtype holding gc program
- x := new(rtype)
- x.align = ptrSize
+ x := &rtype{
+ align: ptrSize,
+ size: offset,
+ ptrdata: uintptr(ptrmap.n) * ptrSize,
+ }
if runtime.GOARCH == "amd64p32" {
x.align = 8
}
- x.size = offset
- x.ptrdata = uintptr(ptrmap.n) * ptrSize
if ptrmap.n > 0 {
x.gcdata = &ptrmap.data[0]
} else {