x86/x86asm: make x86asm.Decode thread-safe Moves initialization of the decoderCover variable from happening unconditionally to only being initialized by the test code using it so that it does not cause a data race when not being used and Decode is called in parallel. Fixes golang/go#33532 Change-Id: I64d748f94d135f0c1f55f1456ff770ac5205c85a GitHub-Last-Rev: 679e78ed1daf3ddbd03792155e3be90b7b498fc4 GitHub-Pull-Request: golang/arch#4 Reviewed-on: https://go-review.googlesource.com/c/arch/+/189919 Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/x86/x86asm/decode.go b/x86/x86asm/decode.go index 250000e..8c98497 100644 --- a/x86/x86asm/decode.go +++ b/x86/x86asm/decode.go
@@ -218,7 +218,6 @@ // decoderCover records coverage information for which parts // of the byte code have been executed. -// TODO(rsc): This is for testing. Only use this if a flag is given. var decoderCover []bool // Decode decodes the leading bytes in src as a single instruction. @@ -462,9 +461,6 @@ // opshift gives the shift to use when saving the next // opcode byte into inst.Opcode. opshift = 24 - if decoderCover == nil { - decoderCover = make([]bool, len(decoder)) - } // Decode loop, executing decoder program. var oldPC, prevPC int @@ -476,7 +472,9 @@ println("run", pc) } x := decoder[pc] - decoderCover[pc] = true + if decoderCover != nil { + decoderCover[pc] = true + } pc++ // Read and decode ModR/M if needed by opcode.
diff --git a/x86/x86asm/ext_test.go b/x86/x86asm/ext_test.go index 526ef5a..e63f113 100644 --- a/x86/x86asm/ext_test.go +++ b/x86/x86asm/ext_test.go
@@ -100,6 +100,11 @@ generate func(f func([]byte)), allowedMismatch func(text string, size int, inst *Inst, dec ExtInst) bool, ) { + decoderCover = make([]bool, len(decoder)) + defer func() { + decoderCover = nil + }() + start := time.Now() ext := &ExtDis{ Dec: make(chan ExtInst),