Ph.D. Research undertaken at the Department of Computer Science at the University of Manchester A DYNAMIC BINARY TRANSLATOR IN A JAVA ENVIRONMENT Ian Rogers Abstract Dynamic binary translation looks to map one computer architecture to another. Java is unusual in that it compiles to a platform independent bytecode that runs on a virtual machine. This paper shows a dynamic translation and compilation environment that can provide a Java virtual machine (JVM). Furthermore, dynamic compilation has the ability to perform run-time optimisations that are unavailable to a conventional static compiler. A technique is shown that translates Java bytecodes in sympathy with dynamic compiler optimisations. This is done with the aim of rivalling and surpassing static optimisation techniques using dynamic ones. This will enable Java to stay true to its goal of being platform independent and yet running at comparable speeds to statically compiled code. Results from the Dynamite JVM, developed as part of this research, are presented. 1 Introduction The Java environment was developed in 1995 [Gosling, McGilton, 1995]. Features from many programming languages and program language libraries were combined into a system that set out to be platform independent. The growth in Java’s libraries and some alterations to the original language specification have led to Java’s continual growth as a commercial programming language and tool. For instance, in a recent survey Java was cited as the most in demand IT job skill [Computer, 2000]. By being so ambitious with its features, Java has suffered from lower performance than rival programming languages such as C++, which it was hoped it to would replace. A key reason for the low performance was the execution of the platform independent bytecodes, with in a Java virtual machine, rather than static compilation. To speed up the execution of these bytecodes Java virtual machines optimised the bytecodes they were interpreting [Lindholm, Yellin, 1999]. Hardware was also developed that could execute Java bytecodes [O’Connor, Tremblay, 1997]. The hardware technique has found a niche in embedded devices where a Java environment needs to be compact as well as fast [Cormie, 2000]. Legacy computers and CPUs unwilling to compromise their native instruction speed were left with interpretation as their Java virtual machine environment. This has led to the invention of Just- in-Time (JIT) and dynamic Java compilers 1 . Just-in-Time compilation compiles a Java class or method the first time it is accessed. Example Just- in-Time compilers are Symantec’s JIT compiler that came with Microsoft Windows versions of the Sun Java Development Kit [Symantec, 1998] up until Java 2 version 1.3, and Microsoft’s own JVM [Microsoft, 2001]. Just-in-Time compilation slows the execution of the Java program, but it is hoped by executing the compiled methods rather than interpreting the Java bytecodes the time will be made up. Often this approach is naïve as not all code in a class or a method is executed within a run of a program. Some bytecodes are only executed once and don’t warrant compilation as interpretation would be faster. Dynamic compilers compile Java bytecodes when it is appropriate. The compiled bytecodes may be a small part of a method or they could span several methods. The dynamic compiler may also have an interpreter to interpret bytecodes which won’t be executed frequently. It is appropriate to compile bytecodes when the cost of the time spent compiling will be more than regained by executing the faster compiled code. This can only be known in retrospect, so dynamic compilers rely on profiling information to gather statistics about the run of a program and to predict where a speed up can be achieved. This also allows expensive compiler optimisations, such as method inlining, to be targeted. These optimisations may break the Java virtual machine specification, but by placing checks around the optimised code a safe fall back can be used when the optimisation is unsafe. Run- time optimisation can’t be performed by a static compilers as they must ensure the code produce will work in all circumstances. Dynamic compilers are a new form of Java virtual machine that have only appeared recently. This paper looks at the development and optimisation of the Dynamite JVM which falls into the dynamic compiler category of Java virtual machine. The Dynamite JVM is novel as it builds on work for the Dynamite dynamic binary translator [Souloglou, 1 Static compilers for Java have also been developed [Free, 2001]. As these are unable to load and execute Java class files dynamically they do not meet the Java virtual machine specification [Lindholm, Yellin, 1999]. The author therefore omits their discussion.