JITs also modify the code at the destination of the function pointer, which was likely also code at a different time (since it usually needs to be allocated from a separate heap that is marked executable). If the CPU prefetched/cached the instructions at the function pointer target prior to the modification, then the program would observe incorrect behavior, even though it's not self-modifying code in the usual sense.