YETI: a graduallY Extensible Trace Interpreter

Mathew Zaleski, Angela Demke Brown, Kevin Stoodley

Proceedings of the 3rd international conference on Virtual Execution Environments (VEE), San Diego, CA, June 2007

 

Abstract

<p>The design of new programming languages benefits from interpretation, which can provide a simple initial implementation, flexibility to explore new language features, and portability to many platforms. The only downside is speed of execution, as there remains a large performance gap between even efficient interpreters and mixed-mode systems that include a just-in-time compiler (or JIT for short). Augmenting an interpreter with a JIT, however, is not a small task. Today, JITs used for JavaTM are loosely-coupled with the interpreter, with callsites of methods being the only transition point between interpreted and native code. To compile whole methods, the JIT must duplicate a sizable amount of functionality already provided by the interpreter, leading to a “big bang” development effort before the JIT can be deployed. Instead, adding a JIT to an interpreter would be easier if it were possible to leverage the existing functionality.</p> <p>&nbsp;</p> <p>In earlier work we showed that packaging virtual instructions as lightweight callable routines is an efficient way to build an interpreter. In this paper we describe how callable bodies help our interpreter to efficiently identify and run traces. Our closely coupled dynamic compiler can fall back on the interpreter in various ways, permitting an incremental approach in which additional performance gains can be realized as it is extended in two dimensions: (i) generating code for more types of virtual instructions, and (ii) identifying larger compilation units. Currently, Yeti identifies straight line regions of code and traces, and generates non-optimized code for roughly 50 Java integer and object bytecodes. Yeti runs roughly twice as fast as a direct-threaded interpreter on SPECjvm98 benchmarks.</p>

 

Manuscript

Pdf

 

Bibtex

Bib