Commit adb1e67f authored by Dave Cheney's avatar Dave Cheney

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: default avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent b6e3a98c
......@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment