From ecba13c38eff6d557a0ea3b6499cc9ba6925c02b Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 31 Oct 2024 07:04:07 +0800 Subject: [PATCH] internal/lib/reflect: use sync.Map --- internal/lib/reflect/type.go | 77 +++++++++++++++++------------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/internal/lib/reflect/type.go b/internal/lib/reflect/type.go index 4b6f4410..a1773775 100644 --- a/internal/lib/reflect/type.go +++ b/internal/lib/reflect/type.go @@ -1024,19 +1024,8 @@ func rtypeOf(i any) *abi.Type { return eface.typ } -/* TODO(xsw): // ptrMap is the cache for PointerTo. var ptrMap sync.Map // map[*rtype]*ptrType -*/ - -var ptrMap struct { - sync.Mutex - m map[*rtype]*ptrType -} - -func init() { - ptrMap.m = make(map[*rtype]*ptrType) -} // PtrTo returns the pointer type with element t. // For example, if t represents type Foo, PtrTo(t) represents *Foo. @@ -1057,8 +1046,8 @@ func (t *rtype) ptrTo() *abi.Type { return at.PtrToThis_ } // Check the cache. - if pi, ok := ptrMap.m[t]; ok { - return &pi.Type + if pi, ok := ptrMap.Load(t); ok { + return &pi.(*ptrType).Type } // Look in known types. @@ -1093,10 +1082,8 @@ func (t *rtype) ptrTo() *abi.Type { pp.Elem = at - ptrMap.m[t] = &pp - return &pp.Type - //pi, _ := ptrMap.LoadOrStore(t, &pp) - //return &pi.(*ptrType).Type + pi, _ := ptrMap.LoadOrStore(t, &pp) + return &pi.(*ptrType).Type } func ptrTo(t *abi.Type) *abi.Type { @@ -1300,31 +1287,27 @@ func haveIdenticalUnderlyingType(T, V *abi.Type, cmpTags bool) bool { func SliceOf(t Type) Type { typ := t.common() - /* TODO(xsw): no cache // Look in cache. ckey := cacheKey{Slice, typ, nil, 0} if slice, ok := lookupCache.Load(ckey); ok { return slice.(Type) } - // Look in known types. - s := "[]" + stringFor(typ) - for _, tt := range typesByString(s) { - slice := (*sliceType)(unsafe.Pointer(tt)) - if slice.Elem == typ { - ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt)) - return ti.(Type) + /* + // Look in known types. + s := "[]" + stringFor(typ) + for _, tt := range typesByString(s) { + slice := (*sliceType)(unsafe.Pointer(tt)) + if slice.Elem == typ { + ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt)) + return ti.(Type) + } } - } */ slice := runtime.SliceOf(typ) - - // TODO(xsw): - // ti, _ := lookupCache.LoadOrStore(ckey, toRType(&slice.Type)) - // return ti.(Type) - - return toType(slice) + ti, _ := lookupCache.LoadOrStore(ckey, toRType(slice)) + return ti.(Type) } // toType converts from a *rtype to a Type that can be returned @@ -1339,6 +1322,19 @@ func toType(t *abi.Type) Type { return toRType(t) } +// The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups. +var lookupCache sync.Map // map[cacheKey]*rtype + +// A cacheKey is the key for use in the lookupCache. +// Four values describe any of the types we are looking for: +// type kind, one or two subtypes, and an extra integer. +type cacheKey struct { + kind Kind + t1 *abi.Type + t2 *abi.Type + extra uintptr +} + // The funcLookupCache caches FuncOf lookups. // FuncOf does not share the common lookupCache since cacheKey is not // sufficient to represent functions unambiguously. @@ -1347,11 +1343,7 @@ var funcLookupCache struct { // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf. // Elements of m are append-only and thus safe for concurrent reading. - m map[uint32][]*abi.Type -} - -func init() { - funcLookupCache.m = make(map[uint32][]*abi.Type) + m sync.Map } // FuncOf returns the function type with the given argument and result types. @@ -1402,8 +1394,8 @@ func FuncOf(in, out []Type, variadic bool) Type { defer funcLookupCache.Unlock() // Look in cache. - if ts, ok := funcLookupCache.m[hash]; ok { - for _, t := range ts { + if ts, ok := funcLookupCache.m.Load(hash); ok { + for _, t := range ts.([]*abi.Type) { if haveIdenticalUnderlyingType(&ft.Type, t, true) { return toRType(t) } @@ -1411,8 +1403,11 @@ func FuncOf(in, out []Type, variadic bool) Type { } addToCache := func(tt *abi.Type) Type { - rts := funcLookupCache.m[hash] - funcLookupCache.m[hash] = append(rts, tt) + var rts []*abi.Type + if rti, ok := funcLookupCache.m.Load(hash); ok { + rts = rti.([]*abi.Type) + } + funcLookupCache.m.Store(hash, append(rts, tt)) return toType(tt) } str := funcStr(ft)