]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: avoid zeroing memory that will be overwritten
authorDave Cheney <dave@cheney.net>
Sun, 28 Aug 2016 23:44:50 +0000 (09:44 +1000)
committerDave Cheney <dave@cheney.net>
Tue, 30 Aug 2016 08:08:37 +0000 (08:08 +0000)
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>

src/reflect/type.go

index 94c5d020c6a4cf56061f4be02acd3c0d72e1c6e5..98cc9ceded283b59e5d5eb11ed7b94c6c0d5a8ef 100644 (file)
@@ -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 {