mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-11 00:00:22 +02:00
ARM64 branches have fairly small relative distances they can encode. These can be +-1MB, or even +-32KB. The largest relative branch is +-128MB, which we already set as an upper limit of our block JIT cache size. We have for a long time just compiled these without checking with the expectation that things just happen to work. We didn't hit the asserts so it was relatively low priority. Apparently now with Steam and a MaxInst limit of 5000, we are now hitting an assert where we are encoding too large of a range. Implement support for long jumping from anywhere in the JIT for when a long jump tries to be encoded and fails, allowing us to restart the JIT at any moment. This is implemented as a long jump when this singular feature could have gotten away with some sort of invasive check and early exit path for two reasons. For one, that would be even more invasive, effectively doing try-catch logic manually. And two, the next step is supporting JIT buffer overflow for when our block size heuristic fails. This next step will mandate longjump on SIGSEGV (with cooperative interaction with the frontend) from effectively /anywhere/ in the JIT. One of the design goals of the CodeEmitter is that every code emission function doesn't do a size remaining check to allow the compiler to do some very effective optimization of emitting code blocks to memory (and it works!). But we lose the ability to sanely size check. When writing the emitter I knew we were going to need to write this cooperative guard page handler, and we're finally at a point where it needs to be done. This will be in the next PR although.