Possibly Address Intel JCC Erratum Performance Issues in JIT
In November Intel released information about a processor bug that occurs when various branch instructions fall on 64-byte boundaries, This includes jcc (conditional jumps), unconditional jumps, call, and ret. The affected processors include a number of Xeon and Core-iX processors from the 6th to 10th generations.
Intel also released updated microcode for these processors to address the bug. The fix, however, carries a performance penalty if the instructions in question cross or are located at the end of a 32-byte boundary. Intel released a white paper detailing how to mitigate this penalty and submitted patches for GNU binutils.
So we should probably investigate mitigation in the SourcePawn JIT as well. I came across patches and discussions about this problem for LLVM, Mozilla Firefox's JavaScript JIT, and Microsoft .NET which may elucidate further. I've linked them below.
I'm unsure of the best way to handle this whole thing, but one thought is to only bother mitigating when running on the affected processors. This would require using the cpuid instruction to identify the processor family/stepping and the microcode revision. I could be wrong, but I don't believe there's a feature flag that would easily identify a processor requiring the mitigation.
I'll also note that the GNU binutils patches are different from what LLVM appears to be doing. The binutils patch follows the mitigation paper by inserting a meaningless prefix on instructions to align the jumps. In particular it uses the SS or DS segment prefix for 32-bit code. The LLVM patch seems to just use plain old nop instructions. Is one method better than the other or does it not really matter? I have no idea at this time.
It would also be worth doing some benchmarking to see how much we are actually impacted by this. If needed, I have a system with a 7th generation Kaby Lake CPU that is supposed to be affected.
- Intel Processor Errata (See erratum 134)
- Intel's JCC Erratum Mitigation Paper(Also lists affected processors)
- GNU Binutils Patches
- LLVM Patches
- Mozilla Bug 1596565
- Dot NET Issue