mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
b6e3a98cf3
commit
adb1e67f02
1 changed files with 22 additions and 25 deletions
|
|
@ -1456,25 +1456,24 @@ func (t *rtype) ptrTo() *rtype {
|
||||||
|
|
||||||
// Create a new ptrType starting with the description
|
// Create a new ptrType starting with the description
|
||||||
// of an *unsafe.Pointer.
|
// of an *unsafe.Pointer.
|
||||||
p = new(ptrType)
|
|
||||||
var iptr interface{} = (*unsafe.Pointer)(nil)
|
var iptr interface{} = (*unsafe.Pointer)(nil)
|
||||||
prototype := *(**ptrType)(unsafe.Pointer(&iptr))
|
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
|
// For the type structures linked into the binary, the
|
||||||
// compiler provides a good hash of the string.
|
// compiler provides a good hash of the string.
|
||||||
// Create a good hash for the new string by using
|
// Create a good hash for the new string by using
|
||||||
// the FNV-1 hash's mixing function to combine the
|
// the FNV-1 hash's mixing function to combine the
|
||||||
// old hash and the new "*".
|
// 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()
|
ptrMap.Unlock()
|
||||||
return &p.rtype
|
return &pp.rtype
|
||||||
}
|
}
|
||||||
|
|
||||||
// fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
|
// 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.
|
// Make a channel type.
|
||||||
var ichan interface{} = (chan unsafe.Pointer)(nil)
|
var ichan interface{} = (chan unsafe.Pointer)(nil)
|
||||||
prototype := *(**chanType)(unsafe.Pointer(&ichan))
|
prototype := *(**chanType)(unsafe.Pointer(&ichan))
|
||||||
ch := new(chanType)
|
ch := *prototype
|
||||||
*ch = *prototype
|
|
||||||
ch.tflag = 0
|
ch.tflag = 0
|
||||||
ch.dir = uintptr(dir)
|
ch.dir = uintptr(dir)
|
||||||
ch.str = resolveReflectName(newName(s, "", "", false))
|
ch.str = resolveReflectName(newName(s, "", "", false))
|
||||||
|
|
@ -1896,8 +1894,7 @@ func MapOf(key, elem Type) Type {
|
||||||
|
|
||||||
// Make a map type.
|
// Make a map type.
|
||||||
var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
|
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.str = resolveReflectName(newName(s, "", "", false))
|
||||||
mt.tflag = 0
|
mt.tflag = 0
|
||||||
mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
|
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 := &rtype{
|
||||||
b.align = ptrSize
|
align: ptrSize,
|
||||||
|
size: size,
|
||||||
|
kind: kind,
|
||||||
|
ptrdata: ptrdata,
|
||||||
|
gcdata: gcdata,
|
||||||
|
}
|
||||||
if overflowPad > 0 {
|
if overflowPad > 0 {
|
||||||
b.align = 8
|
b.align = 8
|
||||||
}
|
}
|
||||||
b.size = size
|
|
||||||
b.ptrdata = ptrdata
|
|
||||||
b.kind = kind
|
|
||||||
b.gcdata = gcdata
|
|
||||||
s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
|
s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
|
||||||
b.str = resolveReflectName(newName(s, "", "", false))
|
b.str = resolveReflectName(newName(s, "", "", false))
|
||||||
return b
|
return b
|
||||||
|
|
@ -2285,8 +2283,7 @@ func SliceOf(t Type) Type {
|
||||||
// Make a slice type.
|
// Make a slice type.
|
||||||
var islice interface{} = ([]unsafe.Pointer)(nil)
|
var islice interface{} = ([]unsafe.Pointer)(nil)
|
||||||
prototype := *(**sliceType)(unsafe.Pointer(&islice))
|
prototype := *(**sliceType)(unsafe.Pointer(&islice))
|
||||||
slice := new(sliceType)
|
slice := *prototype
|
||||||
*slice = *prototype
|
|
||||||
slice.tflag = 0
|
slice.tflag = 0
|
||||||
slice.str = resolveReflectName(newName(s, "", "", false))
|
slice.str = resolveReflectName(newName(s, "", "", false))
|
||||||
slice.hash = fnv1(typ.hash, '[')
|
slice.hash = fnv1(typ.hash, '[')
|
||||||
|
|
@ -2830,8 +2827,7 @@ func ArrayOf(count int, elem Type) Type {
|
||||||
// Make an array type.
|
// Make an array type.
|
||||||
var iarray interface{} = [1]unsafe.Pointer{}
|
var iarray interface{} = [1]unsafe.Pointer{}
|
||||||
prototype := *(**arrayType)(unsafe.Pointer(&iarray))
|
prototype := *(**arrayType)(unsafe.Pointer(&iarray))
|
||||||
array := new(arrayType)
|
array := *prototype
|
||||||
*array = *prototype
|
|
||||||
array.str = resolveReflectName(newName(s, "", "", false))
|
array.str = resolveReflectName(newName(s, "", "", false))
|
||||||
array.hash = fnv1(typ.hash, '[')
|
array.hash = fnv1(typ.hash, '[')
|
||||||
for n := uint32(count); n > 0; n >>= 8 {
|
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)
|
offset += -offset & (ptrSize - 1)
|
||||||
|
|
||||||
// build dummy rtype holding gc program
|
// build dummy rtype holding gc program
|
||||||
x := new(rtype)
|
x := &rtype{
|
||||||
x.align = ptrSize
|
align: ptrSize,
|
||||||
|
size: offset,
|
||||||
|
ptrdata: uintptr(ptrmap.n) * ptrSize,
|
||||||
|
}
|
||||||
if runtime.GOARCH == "amd64p32" {
|
if runtime.GOARCH == "amd64p32" {
|
||||||
x.align = 8
|
x.align = 8
|
||||||
}
|
}
|
||||||
x.size = offset
|
|
||||||
x.ptrdata = uintptr(ptrmap.n) * ptrSize
|
|
||||||
if ptrmap.n > 0 {
|
if ptrmap.n > 0 {
|
||||||
x.gcdata = &ptrmap.data[0]
|
x.gcdata = &ptrmap.data[0]
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue