Thursday, September 24, 2009

JPC: An x86 PC Emulator in Pure Java

JPC is an emulator for x86 machine code written in Java. Chapter 9 of Beautiful Architecture describes its rationale, development as well as challenges in creating an emulator in Java. The bulk of the chapter is organized around nine tips for creating fast Java code. An emulator in this context is a piece of software that reads instructions in a machine language and then executes these instructions. As such it is basically not much more than a specialized interpreter for machine code. The benefit emulators as opposed to virtual machines is that they reads and executes machine code instead of running it directly on the host machine. They are therefore more flexible and can support running one type of machine code on a completely different machine. The JPC emulator in this chapter does exactly this as it interprets x86 code while it itself is running on a JVM. The fact that the JVM often happen to be running on an x86 machine (giving the ironic emulation chain x86->Bytecode->x86) is not relevant for JPC and indeed they do provide examples of JPC being able to emulate x86 on other architectures. The downside of emulators as opposed to VMs on the other hand is that they are slower. Instead of just running the program instructions and then trapping system calls they have to read, interpret and run every instruction which adds overhead.

The chapter begins and ends with the authors arguing why one would want to write an emulator in Java since it does add some overhead that native code doesn't have (even though the overhead is less and less as technology matures). The main two benefits they describe which are specific to a Java emulator is safety and portability. They argue that since JPC is running inside the fairly secure JVM such a system is more secure. This is based on the fact that one have several layers of security and an attacker therefore have to find bugs in more than one place to break all the way into the native environment. The second benefit, namely portability, stems from the fact that Java Virtual Machines are available for more platforms than the x86 which means these platforms can use it to run x86 code without having to port the emulator.

When reading this chapter I liked the way they balanced the opposing forces of simplicity and efficiency. Instead of just deciding that it has to go fast so let us optimize everything they tried to pinpoint the areas where it was actually needed while keeping the rest of the system as simple as possible. They seemed to pay for complexity in some parts with simplicity in others (maybe the average complexity of a system like this is a better measure than the most complex function). I also found their sometimes very obscure tricks to be fun to read. One thing I did find to be strange however was their comment on using the heuristic that "the typical machine will not exceed 2 GB of physical RAM". I thought we were passed making such assumptions and indeed this one seems to be becoming outdated already.

The moderator for this paper posed the question of whether JPC could be useful for other architectures than x86. I assume he meant this in the sense of running it on another architecture and not of porting it to support another one. I do think this could be very useful. The JVM is very popular on other architectures like the ARM. In fact ARM devices with JVMs are probably far more common than x86 devices since ARM processors are the most sold 32-processors on the planet (They passed the 10 billion processors mark a year ago and around 1 billion are now shipped every quarter). Just look at the (likely) ARM-powered, Java-capable device in your pocket - the cellphone. That being said however a lot of useful software exist only for the x86 architecture so an emulator capable of running this software on medium-sized, non-x86 devices such as smartphones, PDAs and some netbooks would be very useful.

No comments:

Post a Comment