Normally static recompilation of video games breaks down due to self modifying code. If you're going to have to have go through the motions of JIT anyway (and in places where, if they're going through the motions of self modifying code, it's probably computationally expensive code at that), then you might as well go whole hog. That way you only have to build one kind of compiler, and you can take advantage of profile information for everything.
But the 360's security model specifically out rules self modifying code. And this is enforced by the hypervisor; the system is W xor X, and the transition of a page from W to X has to be accompanied by signatures signed by Microsoft's private key. Nobody, including the kernel, can modify their code.
That might make this one of the first platforms where the static recompilation scheme might make sense in the long term architecture of the emulator.
Self modifying code hasn't been common in video games for 20 years. The main problem is that static recompilation requires accurate alias analysis-- knowing what values a given pointer might have at a particular point of execution. This is especially important for indirect calls through function pointers (C++ virtual functions), where entire chunks of code might be missed.
But you can still have video games implement their own form of dynamically loaded modules, which (to a jit) is the same problem as self modifying code. I know several PS2 games do this.
But it's still something to be aware of, so that you don't have to make major architectural changes to your jit so that one game will work. It's a million and one little things like this that make emulators hard.
Yeah, you'd probably want an indirect table for inter-page calls, with maybe a soft TLB for this translation if the profiler gave you good results. You might be able to bank on the idea that any processor you'd be running the generated code on will have so much better branch prediction and speculative execution than the 360, that you'll be able to fit in the cracks even with this extra overhead.
It always seemed like a poor security choice to me, but some game binaries are inexplicably massive and break up easily depending on what phase of the game that you're on.
Sure, in the PS2/gamecube era custom dynamically loaded code mechanisms were common.
But on modern consoles (360, PS3 and later) the OS bans games from loading/generating code. To load code they must call out to the OS, which loads it, checks the signatures and puts it in write protected memory.
It's this security mechanism which makes static recompilation viable for 360/PS3 games.
I wonder if they did this on purpose? Self modifying code has been known to break emulators. Part of a future-proof scalable platform is to provide a way to run the previous generations games and emulation is a really good way to do that cheaply.
But the 360's security model specifically out rules self modifying code. And this is enforced by the hypervisor; the system is W xor X, and the transition of a page from W to X has to be accompanied by signatures signed by Microsoft's private key. Nobody, including the kernel, can modify their code.
That might make this one of the first platforms where the static recompilation scheme might make sense in the long term architecture of the emulator.