internal/lib/reflect: use sync.Map
This commit is contained in:
@@ -1024,19 +1024,8 @@ func rtypeOf(i any) *abi.Type {
|
|||||||
return eface.typ
|
return eface.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(xsw):
|
|
||||||
// ptrMap is the cache for PointerTo.
|
// ptrMap is the cache for PointerTo.
|
||||||
var ptrMap sync.Map // map[*rtype]*ptrType
|
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.
|
// PtrTo returns the pointer type with element t.
|
||||||
// For example, if t represents type Foo, PtrTo(t) represents *Foo.
|
// For example, if t represents type Foo, PtrTo(t) represents *Foo.
|
||||||
@@ -1057,8 +1046,8 @@ func (t *rtype) ptrTo() *abi.Type {
|
|||||||
return at.PtrToThis_
|
return at.PtrToThis_
|
||||||
}
|
}
|
||||||
// Check the cache.
|
// Check the cache.
|
||||||
if pi, ok := ptrMap.m[t]; ok {
|
if pi, ok := ptrMap.Load(t); ok {
|
||||||
return &pi.Type
|
return &pi.(*ptrType).Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look in known types.
|
// Look in known types.
|
||||||
@@ -1093,10 +1082,8 @@ func (t *rtype) ptrTo() *abi.Type {
|
|||||||
|
|
||||||
pp.Elem = at
|
pp.Elem = at
|
||||||
|
|
||||||
ptrMap.m[t] = &pp
|
pi, _ := ptrMap.LoadOrStore(t, &pp)
|
||||||
return &pp.Type
|
return &pi.(*ptrType).Type
|
||||||
//pi, _ := ptrMap.LoadOrStore(t, &pp)
|
|
||||||
//return &pi.(*ptrType).Type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ptrTo(t *abi.Type) *abi.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 {
|
func SliceOf(t Type) Type {
|
||||||
typ := t.common()
|
typ := t.common()
|
||||||
|
|
||||||
/* TODO(xsw): no cache
|
|
||||||
// Look in cache.
|
// Look in cache.
|
||||||
ckey := cacheKey{Slice, typ, nil, 0}
|
ckey := cacheKey{Slice, typ, nil, 0}
|
||||||
if slice, ok := lookupCache.Load(ckey); ok {
|
if slice, ok := lookupCache.Load(ckey); ok {
|
||||||
return slice.(Type)
|
return slice.(Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look in known types.
|
/*
|
||||||
s := "[]" + stringFor(typ)
|
// Look in known types.
|
||||||
for _, tt := range typesByString(s) {
|
s := "[]" + stringFor(typ)
|
||||||
slice := (*sliceType)(unsafe.Pointer(tt))
|
for _, tt := range typesByString(s) {
|
||||||
if slice.Elem == typ {
|
slice := (*sliceType)(unsafe.Pointer(tt))
|
||||||
ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
|
if slice.Elem == typ {
|
||||||
return ti.(Type)
|
ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
|
||||||
|
return ti.(Type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
slice := runtime.SliceOf(typ)
|
slice := runtime.SliceOf(typ)
|
||||||
|
ti, _ := lookupCache.LoadOrStore(ckey, toRType(slice))
|
||||||
// TODO(xsw):
|
return ti.(Type)
|
||||||
// ti, _ := lookupCache.LoadOrStore(ckey, toRType(&slice.Type))
|
|
||||||
// return ti.(Type)
|
|
||||||
|
|
||||||
return toType(slice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// toType converts from a *rtype to a Type that can be returned
|
// 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)
|
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.
|
// The funcLookupCache caches FuncOf lookups.
|
||||||
// FuncOf does not share the common lookupCache since cacheKey is not
|
// FuncOf does not share the common lookupCache since cacheKey is not
|
||||||
// sufficient to represent functions unambiguously.
|
// 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.
|
// 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.
|
// Elements of m are append-only and thus safe for concurrent reading.
|
||||||
m map[uint32][]*abi.Type
|
m sync.Map
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
funcLookupCache.m = make(map[uint32][]*abi.Type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FuncOf returns the function type with the given argument and result types.
|
// 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()
|
defer funcLookupCache.Unlock()
|
||||||
|
|
||||||
// Look in cache.
|
// Look in cache.
|
||||||
if ts, ok := funcLookupCache.m[hash]; ok {
|
if ts, ok := funcLookupCache.m.Load(hash); ok {
|
||||||
for _, t := range ts {
|
for _, t := range ts.([]*abi.Type) {
|
||||||
if haveIdenticalUnderlyingType(&ft.Type, t, true) {
|
if haveIdenticalUnderlyingType(&ft.Type, t, true) {
|
||||||
return toRType(t)
|
return toRType(t)
|
||||||
}
|
}
|
||||||
@@ -1411,8 +1403,11 @@ func FuncOf(in, out []Type, variadic bool) Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addToCache := func(tt *abi.Type) Type {
|
addToCache := func(tt *abi.Type) Type {
|
||||||
rts := funcLookupCache.m[hash]
|
var rts []*abi.Type
|
||||||
funcLookupCache.m[hash] = append(rts, tt)
|
if rti, ok := funcLookupCache.m.Load(hash); ok {
|
||||||
|
rts = rti.([]*abi.Type)
|
||||||
|
}
|
||||||
|
funcLookupCache.m.Store(hash, append(rts, tt))
|
||||||
return toType(tt)
|
return toType(tt)
|
||||||
}
|
}
|
||||||
str := funcStr(ft)
|
str := funcStr(ft)
|
||||||
|
|||||||
Reference in New Issue
Block a user