The traditional mitigation is to use hardware tagging and permit the tag bits to be set only via a privileged instruction, e.g. Multics. The x86 segmented memory model also allowed this, and I used this to build some experimental SUID memory-mapped the 1990s (you could call into them via special gates, but not read the instruction memory, for example). Although you those memory models are still supported on x86 for back compatibility I don’t believe they are particularly fast any more, unfortunately.
Edit: The lowrisc (RISC v) folks are implementing tagged memory also btw