Self Modifying Code (Code Checking) - nonarkitten/monkeymonkeyjit GitHub Wiki

Any general purpose 68000 system, such as the Atari ST, Commodore Amiga or Sharp X68000, must support self-modifying code -- in the strictest sense, any system that's using dynamical allocation for programs is employing self-modifying code. Traditionally, the term was only used to describe the modification of code by the software itself, usually immediately before executing it, but the way in which we handle this is the same as with dynamic memory allocation and general program executing.

When any block of code is compiled, we generate a simple 32-bit checksum (sum of each SOURCE word from the block); this should be lightweight enough to not impact performance too much and robust enough to detect any modifications. The length of this block is also recorded. When re-executing a block, the emulator will retest the entire block and only execute the old version if the checksum is a match.

This only needs to be done when executing code from RAM, so each system will have a test. This is done with a small array of 256 boolean values for each 64KB "page" within the 68000 memory space. And page that is "true" will be rechecked before executing code.

SNK NEO-GEO:     $10-$1F
Sega Mega Drive: $FF
Commodore Amiga: $00-$9F, $C0-$D7
Atari ST:        $00-$CF

Note that this is not (necessarily) the same as "Paged Memory Mode". The JIT itself is performing this lookup before entering a block of code. Only memory within these regions will get checked -- all other memory locations will be JIT-ed only once.