aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json/encode.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/json/encode.go')
-rw-r--r--src/encoding/json/encode.go32
1 files changed, 5 insertions, 27 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index 68512d0225..e7e7c4b7ef 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -21,7 +21,6 @@ import (
"strconv"
"strings"
"sync"
- "sync/atomic"
"unicode"
"unicode/utf8"
)
@@ -1258,34 +1257,13 @@ func dominantField(fields []field) (field, bool) {
return fields[0], true
}
-var fieldCache struct {
- value atomic.Value // map[reflect.Type][]field
- mu sync.Mutex // used only by writers
-}
+var fieldCache sync.Map // map[reflect.Type][]field
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
func cachedTypeFields(t reflect.Type) []field {
- m, _ := fieldCache.value.Load().(map[reflect.Type][]field)
- f := m[t]
- if f != nil {
- return f
- }
-
- // Compute fields without lock.
- // Might duplicate effort but won't hold other computations back.
- f = typeFields(t)
- if f == nil {
- f = []field{}
+ if f, ok := fieldCache.Load(t); ok {
+ return f.([]field)
}
-
- fieldCache.mu.Lock()
- m, _ = fieldCache.value.Load().(map[reflect.Type][]field)
- newM := make(map[reflect.Type][]field, len(m)+1)
- for k, v := range m {
- newM[k] = v
- }
- newM[t] = f
- fieldCache.value.Store(newM)
- fieldCache.mu.Unlock()
- return f
+ f, _ := fieldCache.LoadOrStore(t, typeFields(t))
+ return f.([]field)
}