Check Burroughs B5000 (now Unisys ClearPath), AS/400 (now IBM I), z/OS (now IBM z), Xerox PARC workstations, Lilith, Ceres, watch OS, Garmin devices and plenty of others.
p-System never did JIT. Remember this was for machines with 64 K of memory. Not 64 MB. But 64 K! The p-Code was much more compact than native code. Interpreting most code was plenty fast for most things -- even on the slow (under 10 MHz) clock speeds of the era. Critical operations could be written in assembler. The p-System had its own assembler for native code.
JVM is a whole other world. Adding GC is a whole new dimension in complexity. But decades of research have gone into the JVM making it the amazing runtime platform it is today.
https://en.wikipedia.org/wiki/Pascal_MicroEngine
https://en.wikipedia.org/wiki/Corvus_Systems
Adding a GC to bytecode systems, is what Xerox PARC did with their Interlisp-D, Smalltalk and Mesa/Cedar workstations.
The CPUs were microcoded and as part of the boot process they would load the respective hardware interpreter for the environment being booted into the workstation.
A similar idea was explored in one of Oberon's implementations, where instead of using straight native code like on the Ceres workstation, the modules would have a compact representation, JITed into native code on module load.
See section 7, Machine-Independent Mobile Code on http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.90....
Taos articles link at the bottom, Byte, IEEE, Edge etc.
This reminds me of the UCSD p-System of the early 1980's.
To port the OS all you had to port was the very small p-Machine emulator (PME). Once you had a bootable PME, everything else, the entire OS, utilities, and all applications instantly came along for the ride, without even being recompiled.
I could only imagine a modern OS that would take an approach like this, but Hotspot JIT everything to native code.