go-json/encode_compile_race.go

45 lines
929 B
Go
Raw Normal View History

2021-02-01 14:02:43 +03:00
// +build race
package json
import (
"sync"
"unsafe"
)
var setsMu sync.RWMutex
func encodeCompileToGetCodeSet(typeptr uintptr) (*opcodeSet, error) {
2021-02-09 15:37:18 +03:00
if typeptr > maxTypeAddr {
2021-02-01 14:02:43 +03:00
return encodeCompileToGetCodeSetSlowPath(typeptr)
}
2021-02-09 15:37:18 +03:00
index := typeptr - baseTypeAddr
2021-02-01 14:02:43 +03:00
setsMu.RLock()
2021-02-09 15:37:18 +03:00
if codeSet := cachedOpcodeSets[index]; codeSet != nil {
2021-02-01 14:02:43 +03:00
setsMu.RUnlock()
return codeSet, nil
}
setsMu.RUnlock()
// noescape trick for header.typ ( reflect.*rtype )
copiedType := *(**rtype)(unsafe.Pointer(&typeptr))
code, err := encodeCompileHead(&encodeCompileContext{
typ: copiedType,
structTypeToCompiledCode: map[uintptr]*compiledCode{},
})
if err != nil {
return nil, err
}
code = copyOpcode(code)
codeLength := code.totalLength()
codeSet := &opcodeSet{
code: code,
codeLength: codeLength,
}
setsMu.Lock()
2021-02-09 15:37:18 +03:00
cachedOpcodeSets[index] = codeSet
2021-02-01 14:02:43 +03:00
setsMu.Unlock()
return codeSet, nil
}