Skip to content

Commit adb1e67

Browse files
committed
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 <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent b6e3a98 commit adb1e67

File tree

1 file changed

+22
-25
lines changed

1 file changed

+22
-25
lines changed

src/reflect/type.go

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,25 +1456,24 @@ func (t *rtype) ptrTo() *rtype {
14561456

14571457
// Create a new ptrType starting with the description
14581458
// of an *unsafe.Pointer.
1459-
p = new(ptrType)
14601459
var iptr interface{} = (*unsafe.Pointer)(nil)
14611460
prototype := *(**ptrType)(unsafe.Pointer(&iptr))
1462-
*p = *prototype
1461+
pp := *prototype
14631462

1464-
p.str = resolveReflectName(newName(s, "", "", false))
1463+
pp.str = resolveReflectName(newName(s, "", "", false))
14651464

14661465
// For the type structures linked into the binary, the
14671466
// compiler provides a good hash of the string.
14681467
// Create a good hash for the new string by using
14691468
// the FNV-1 hash's mixing function to combine the
14701469
// old hash and the new "*".
1471-
p.hash = fnv1(t.hash, '*')
1470+
pp.hash = fnv1(t.hash, '*')
14721471

1473-
p.elem = t
1472+
pp.elem = t
14741473

1475-
ptrMap.m[t] = p
1474+
ptrMap.m[t] = &pp
14761475
ptrMap.Unlock()
1477-
return &p.rtype
1476+
return &pp.rtype
14781477
}
14791478

14801479
// 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 {
18521851
// Make a channel type.
18531852
var ichan interface{} = (chan unsafe.Pointer)(nil)
18541853
prototype := *(**chanType)(unsafe.Pointer(&ichan))
1855-
ch := new(chanType)
1856-
*ch = *prototype
1854+
ch := *prototype
18571855
ch.tflag = 0
18581856
ch.dir = uintptr(dir)
18591857
ch.str = resolveReflectName(newName(s, "", "", false))
@@ -1896,8 +1894,7 @@ func MapOf(key, elem Type) Type {
18961894

18971895
// Make a map type.
18981896
var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
1899-
mt := new(mapType)
1900-
*mt = **(**mapType)(unsafe.Pointer(&imap))
1897+
mt := **(**mapType)(unsafe.Pointer(&imap))
19011898
mt.str = resolveReflectName(newName(s, "", "", false))
19021899
mt.tflag = 0
19031900
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 {
22482245
}
22492246
}
22502247

2251-
b := new(rtype)
2252-
b.align = ptrSize
2248+
b := &rtype{
2249+
align: ptrSize,
2250+
size: size,
2251+
kind: kind,
2252+
ptrdata: ptrdata,
2253+
gcdata: gcdata,
2254+
}
22532255
if overflowPad > 0 {
22542256
b.align = 8
22552257
}
2256-
b.size = size
2257-
b.ptrdata = ptrdata
2258-
b.kind = kind
2259-
b.gcdata = gcdata
22602258
s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
22612259
b.str = resolveReflectName(newName(s, "", "", false))
22622260
return b
@@ -2285,8 +2283,7 @@ func SliceOf(t Type) Type {
22852283
// Make a slice type.
22862284
var islice interface{} = ([]unsafe.Pointer)(nil)
22872285
prototype := *(**sliceType)(unsafe.Pointer(&islice))
2288-
slice := new(sliceType)
2289-
*slice = *prototype
2286+
slice := *prototype
22902287
slice.tflag = 0
22912288
slice.str = resolveReflectName(newName(s, "", "", false))
22922289
slice.hash = fnv1(typ.hash, '[')
@@ -2830,8 +2827,7 @@ func ArrayOf(count int, elem Type) Type {
28302827
// Make an array type.
28312828
var iarray interface{} = [1]unsafe.Pointer{}
28322829
prototype := *(**arrayType)(unsafe.Pointer(&iarray))
2833-
array := new(arrayType)
2834-
*array = *prototype
2830+
array := *prototype
28352831
array.str = resolveReflectName(newName(s, "", "", false))
28362832
array.hash = fnv1(typ.hash, '[')
28372833
for n := uint32(count); n > 0; n >>= 8 {
@@ -3071,13 +3067,14 @@ func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uin
30713067
offset += -offset & (ptrSize - 1)
30723068

30733069
// build dummy rtype holding gc program
3074-
x := new(rtype)
3075-
x.align = ptrSize
3070+
x := &rtype{
3071+
align: ptrSize,
3072+
size: offset,
3073+
ptrdata: uintptr(ptrmap.n) * ptrSize,
3074+
}
30763075
if runtime.GOARCH == "amd64p32" {
30773076
x.align = 8
30783077
}
3079-
x.size = offset
3080-
x.ptrdata = uintptr(ptrmap.n) * ptrSize
30813078
if ptrmap.n > 0 {
30823079
x.gcdata = &ptrmap.data[0]
30833080
} else {

0 commit comments

Comments
 (0)