iOS Address Space Limitations
As you may know, I’m the author of the PPSSPP Playstation Portable (PSP) emulator. It runs on Windows, Android, Linux, Mac, and also iOS, unofficially. As a modern emulator, it makes use of JIT compilation to emulate the guest CPU efficiently. iOS has long been an issue because Apple doesn’t let you map memory as RWX, that is, you cant get a block of memory that’s both writable and executable at the same time. It normally doesn’t let you allocate executable memory at all, but it’s possible to get around that for apps you compile yourself. That’s a different topic though.
Anyway, recently I tried to get the emulator running on ARM64 iOS (it has previously only worked as a 32-bit build, which is not great for the latest devices, and iOS will warn about your app begin inefficient). Normally on 64-bit platforms I simply allocate a 4GB block of memory out in space somewhere, and set up the PSP’s memory map there. This works fine because address space is effectively unlimited on 64-bit. However, on iOS, that’s not the case! When doing the allocations I got failures until I reduced the size to around 1 GB.
And the reason, of course, was that the address space is not unlimited - for some reason, perhaps to have more bits for their "tagged pointers" used by Swift and Objective C, they have decided to limit pointers to 33 bits. That is, we should technically be able to address the 8GB address space of 0x000000000 to 0x200000000 (note that these are 9 hex digits long, not 8). In there I’d expect to be able to allocate my block of 0xE1000000 bytes, but no, not possible. Because for some reason, probably to avoid pointer truncation bugs when porting software, they locked out the bottom 4GB as well. So effectively, of the huge 64-bit address space, only the second 4GB block is available to applications.
So in summary:
In 32-bit iOS, you have access to 2 or 3GB of address space.
In 64-bit iOS, you’d expect to be able to access effectively unlimited address space, but in reality Apple has limited it to the 4GB at 0x100000000 to 0x200000000. What a pain.
Anyway, I found a workaround that worked well enough, but that might have to be another article.
Comments are appreciated :) Just e-mail me at firstname.lastname@example.org .