Most modern systems are Princeton in the sense that the same memory system is used for data and instructions, although memory management systems often keep instructions and data in separate pages and user code may not be able to write into memory that contains executable instructions for security reasons.
At a different level, there are typically separate caches for instructions and data. This separation of instruction and data caches helps to overcome the Princeton bottleneck. Furthermore, most modern systems don't ensure cache coherency between the data cache and the instruction cache. This means that if you write new instructions into memory they may not immediately effect execution since the instruction cache might be relying on previously cached instructions. Typically, operating system software has to clear the instruction cache after a new or modified program has been loaded into memory.