mirror of
https://github.com/golang/go
synced 2024-11-23 05:40:04 -07:00
cmd/compile, etc: bring back ptrToThis
This was removed in CL 19695 but it slows down reflect.New, which ends up on the hot path of things like JSON decoding. There is no immediate cost in binary size, but it will make it harder to further shrink run time type information in Go 1.8. Before BenchmarkNew-40 30000000 36.3 ns/op After BenchmarkNew-40 50000000 29.5 ns/op Fixes #16161 Updates #16117 Change-Id: If7cb7f3e745d44678f3f5cf3a5338c59847529d2 Reviewed-on: https://go-review.googlesource.com/24400 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
aa6345d3c9
commit
e369490fb7
@ -820,14 +820,10 @@ func dcommontype(s *Sym, ot int, t *Type) int {
|
||||
algsym = dalgsym(t)
|
||||
}
|
||||
|
||||
var sptr *Sym
|
||||
tptr := Ptrto(t)
|
||||
if !t.IsPtr() && (t.Sym != nil || methods(tptr) != nil) {
|
||||
sptr := dtypesym(tptr)
|
||||
r := obj.Addrel(Linksym(s))
|
||||
r.Off = 0
|
||||
r.Siz = 0
|
||||
r.Sym = sptr.Lsym
|
||||
r.Type = obj.R_USETYPE
|
||||
sptr = dtypesym(tptr)
|
||||
}
|
||||
|
||||
gcsym, useGCProg, ptrdata := dgcsym(t)
|
||||
@ -845,7 +841,7 @@ func dcommontype(s *Sym, ot int, t *Type) int {
|
||||
// alg *typeAlg
|
||||
// gcdata *byte
|
||||
// str nameOff
|
||||
// _ int32
|
||||
// ptrToThis typeOff
|
||||
// }
|
||||
ot = duintptr(s, ot, uint64(t.Width))
|
||||
ot = duintptr(s, ot, uint64(ptrdata))
|
||||
@ -909,8 +905,12 @@ func dcommontype(s *Sym, ot int, t *Type) int {
|
||||
ot = dsymptr(s, ot, gcsym, 0) // gcdata
|
||||
|
||||
nsym := dname(p, "", nil, exported)
|
||||
ot = dsymptrOffLSym(Linksym(s), ot, nsym, 0)
|
||||
ot = duint32(s, ot, 0)
|
||||
ot = dsymptrOffLSym(Linksym(s), ot, nsym, 0) // str
|
||||
if sptr == nil {
|
||||
ot = duint32(s, ot, 0)
|
||||
} else {
|
||||
ot = dsymptrOffLSym(Linksym(s), ot, Linksym(sptr), 0) // ptrToThis
|
||||
}
|
||||
|
||||
return ot
|
||||
}
|
||||
|
@ -5741,3 +5741,10 @@ func TestOffsetLock(t *testing.T) {
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func BenchmarkNew(b *testing.B) {
|
||||
v := TypeOf(XM{})
|
||||
for i := 0; i < b.N; i++ {
|
||||
New(v)
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ type rtype struct {
|
||||
alg *typeAlg // algorithm table
|
||||
gcdata *byte // garbage collection data
|
||||
str nameOff // string form
|
||||
_ int32 // unused; keeps rtype always a multiple of ptrSize
|
||||
ptrToThis typeOff // type for pointer to this type, may be zero
|
||||
}
|
||||
|
||||
// a copy of runtime.typeAlg
|
||||
@ -1430,6 +1430,10 @@ func PtrTo(t Type) Type {
|
||||
}
|
||||
|
||||
func (t *rtype) ptrTo() *rtype {
|
||||
if t.ptrToThis != 0 {
|
||||
return t.typeOff(t.ptrToThis)
|
||||
}
|
||||
|
||||
// Check the cache.
|
||||
ptrMap.RLock()
|
||||
if m := ptrMap.m; m != nil {
|
||||
@ -1927,6 +1931,7 @@ func MapOf(key, elem Type) Type {
|
||||
mt.bucketsize = uint16(mt.bucket.size)
|
||||
mt.reflexivekey = isReflexive(ktyp)
|
||||
mt.needkeyupdate = needKeyUpdate(ktyp)
|
||||
mt.ptrToThis = 0
|
||||
|
||||
return cachePut(ckey, &mt.rtype)
|
||||
}
|
||||
@ -2065,6 +2070,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
|
||||
|
||||
// Populate the remaining fields of ft and store in cache.
|
||||
ft.str = resolveReflectName(newName(str, "", "", false))
|
||||
ft.ptrToThis = 0
|
||||
funcLookupCache.m[hash] = append(funcLookupCache.m[hash], &ft.rtype)
|
||||
|
||||
return &ft.rtype
|
||||
@ -2295,6 +2301,7 @@ func SliceOf(t Type) Type {
|
||||
slice.str = resolveReflectName(newName(s, "", "", false))
|
||||
slice.hash = fnv1(typ.hash, '[')
|
||||
slice.elem = typ
|
||||
slice.ptrToThis = 0
|
||||
|
||||
return cachePut(ckey, &slice.rtype)
|
||||
}
|
||||
@ -2842,6 +2849,7 @@ func ArrayOf(count int, elem Type) Type {
|
||||
}
|
||||
array.hash = fnv1(array.hash, ']')
|
||||
array.elem = typ
|
||||
array.ptrToThis = 0
|
||||
max := ^uintptr(0) / typ.size
|
||||
if uintptr(count) > max {
|
||||
panic("reflect.ArrayOf: array size would exceed virtual address space")
|
||||
|
@ -36,9 +36,9 @@ type _type struct {
|
||||
// gcdata stores the GC type data for the garbage collector.
|
||||
// If the KindGCProg bit is set in kind, gcdata is a GC program.
|
||||
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
|
||||
gcdata *byte
|
||||
str nameOff
|
||||
_ int32
|
||||
gcdata *byte
|
||||
str nameOff
|
||||
ptrToThis typeOff
|
||||
}
|
||||
|
||||
func (t *_type) string() string {
|
||||
|
Loading…
Reference in New Issue
Block a user