<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pdf2xml SYSTEM "pdf2xml.dtd">

<pdf2xml producer="poppler" version="24.02.0">
<page number="1" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="0" size="27" family="TACTGM+NimbusRomNo9L-Medi" color="#000000"/>
	<fontspec id="1" size="16" family="KUYGUP+NimbusRomNo9L-Regu" color="#000000"/>
	<fontspec id="2" size="12" family="DSQVLB+CMSY8" color="#000000"/>
	<fontspec id="3" size="12" family="TLZTLU+CMR8" color="#000000"/>
	<fontspec id="4" size="13" family="KUYGUP+NimbusRomNo9L-Regu" color="#000000"/>
	<fontspec id="5" size="9" family="SJLUHL+CMSY6" color="#000000"/>
	<fontspec id="6" size="13" family="NXYQZX+CMSY9" color="#000000"/>
	<fontspec id="7" size="13" family="RRLDLB+CMTT9" color="#000000"/>
	<fontspec id="8" size="9" family="ACEGLD+CMR6" color="#000000"/>
	<fontspec id="9" size="16" family="TACTGM+NimbusRomNo9L-Medi" color="#000000"/>
	<fontspec id="10" size="13" family="NWBJZL+NimbusRomNo9L-MediItal" color="#000000"/>
	<fontspec id="11" size="13" family="FCXRUF+NimbusRomNo9L-ReguItal" color="#000000"/>
	<fontspec id="12" size="10" family="KUYGUP+NimbusRomNo9L-Regu" color="#000000"/>
	<fontspec id="13" size="10" family="FQDHWA+NimbusRomNo9L-Regu-Slant_167" color="#000000"/>
	<fontspec id="14" size="10" family="ZRUSRO+CMSY7" color="#000000"/>
<text top="118" left="121" width="674" height="24" font="0">Trace-based Just-in-Time Type Specialization for Dynamic</text>
<text top="148" left="396" width="124" height="24" font="0">Languages</text>
<text top="210" left="180" width="83" height="15" font="1">Andreas Gal</text>
<text top="206" left="263" width="6" height="11" font="2">∗</text>
<text top="206" left="270" width="10" height="11" font="3">+</text>
<text top="210" left="281" width="98" height="15" font="1">, Brendan Eich</text>
<text top="206" left="379" width="6" height="11" font="2">∗</text>
<text top="210" left="386" width="92" height="15" font="1">, Mike Shaver</text>
<text top="206" left="478" width="6" height="11" font="2">∗</text>
<text top="210" left="485" width="116" height="15" font="1">, David Anderson</text>
<text top="206" left="601" width="6" height="11" font="2">∗</text>
<text top="210" left="608" width="115" height="15" font="1">, David Mandelin</text>
<text top="206" left="723" width="6" height="11" font="2">∗</text>
<text top="210" left="731" width="4" height="15" font="1">,</text>
<text top="229" left="140" width="171" height="15" font="1">Mohammad R. Haghighat</text>
<text top="226" left="312" width="6" height="11" font="3">$</text>
<text top="229" left="319" width="98" height="15" font="1">, Blake Kaplan</text>
<text top="225" left="417" width="6" height="11" font="2">∗</text>
<text top="229" left="424" width="110" height="15" font="1">, Graydon Hoare</text>
<text top="225" left="534" width="6" height="11" font="2">∗</text>
<text top="229" left="541" width="102" height="15" font="1">, Boris Zbarsky</text>
<text top="225" left="642" width="6" height="11" font="2">∗</text>
<text top="229" left="649" width="114" height="15" font="1">, Jason Orendorff</text>
<text top="225" left="764" width="6" height="11" font="2">∗</text>
<text top="229" left="771" width="4" height="15" font="1">,</text>
<text top="248" left="102" width="106" height="15" font="1">Jesse Ruderman</text>
<text top="245" left="209" width="6" height="11" font="2">∗</text>
<text top="248" left="216" width="95" height="15" font="1">, Edwin Smith</text>
<text top="245" left="310" width="11" height="11" font="3">#</text>
<text top="248" left="322" width="108" height="15" font="1">, Rick Reitmaier</text>
<text top="245" left="430" width="11" height="11" font="3">#</text>
<text top="248" left="441" width="125" height="15" font="1">, Michael Bebenita</text>
<text top="245" left="566" width="10" height="11" font="3">+</text>
<text top="248" left="577" width="100" height="15" font="1">, Mason Chang</text>
<text top="245" left="677" width="21" height="11" font="3">+#</text>
<text top="248" left="699" width="104" height="15" font="1">, Michael Franz</text>
<text top="245" left="802" width="10" height="11" font="3">+</text>
<text top="273" left="399" width="110" height="12" font="4">Mozilla Corporation</text>
<text top="270" left="509" width="6" height="8" font="5">∗</text>
<text top="287" left="136" width="7" height="13" font="6">{</text>
<text top="289" left="143" width="544" height="11" font="7">gal,brendan,shaver,danderson,dmandelin,mrbkap,graydon,bz,jorendorff,jruderman</text>
<text top="287" left="687" width="7" height="13" font="6">}</text>
<text top="289" left="694" width="85" height="11" font="7">@mozilla.com</text>
<text top="312" left="401" width="104" height="12" font="4">Adobe Corporation</text>
<text top="309" left="505" width="9" height="8" font="8">#</text>
<text top="326" left="355" width="7" height="13" font="6">{</text>
<text top="328" left="362" width="120" height="11" font="7">edwsmith,rreitmai</text>
<text top="326" left="482" width="7" height="13" font="6">}</text>
<text top="328" left="489" width="71" height="11" font="7">@adobe.com</text>
<text top="352" left="408" width="93" height="12" font="4">Intel Corporation</text>
<text top="349" left="501" width="5" height="8" font="8">$</text>
<text top="366" left="345" width="7" height="13" font="6">{</text>
<text top="368" left="352" width="141" height="11" font="7">mohammad.r.haghighat</text>
<text top="366" left="493" width="7" height="13" font="6">}</text>
<text top="368" left="500" width="71" height="11" font="7">@intel.com</text>
<text top="390" left="369" width="168" height="12" font="4">University of California, Irvine</text>
<text top="388" left="537" width="8" height="8" font="8">+</text>
<text top="404" left="348" width="7" height="13" font="6">{</text>
<text top="406" left="355" width="148" height="11" font="7">mbebenit,changm,franz</text>
<text top="404" left="503" width="7" height="13" font="6">}</text>
<text top="406" left="510" width="56" height="11" font="7">@uci.edu</text>
<text top="505" left="81" width="61" height="15" font="9">Abstract</text>
<text top="528" left="81" width="359" height="12" font="4">Dynamic languages such as JavaScript are more difficult to com-</text>
<text top="543" left="81" width="359" height="12" font="4">pile than statically typed ones. Since no concrete type information</text>
<text top="558" left="81" width="359" height="12" font="4">is available, traditional compilers need to emit generic code that can</text>
<text top="573" left="81" width="359" height="12" font="4">handle all possible type combinations at runtime. We present an al-</text>
<text top="588" left="81" width="359" height="12" font="4">ternative compilation technique for dynamically-typed languages</text>
<text top="603" left="81" width="359" height="12" font="4">that identifies frequently executed loop traces at run-time and then</text>
<text top="618" left="81" width="359" height="12" font="4">generates machine code on the fly that is specialized for the ac-</text>
<text top="633" left="81" width="359" height="12" font="4">tual dynamic types occurring on each path through the loop. Our</text>
<text top="648" left="81" width="359" height="12" font="4">method provides cheap inter-procedural type specialization, and an</text>
<text top="662" left="81" width="359" height="12" font="4">elegant and efficient way of incrementally compiling lazily discov-</text>
<text top="677" left="81" width="359" height="12" font="4">ered alternative paths through nested loops. We have implemented</text>
<text top="692" left="81" width="359" height="12" font="4">a dynamic compiler for JavaScript based on our technique and we</text>
<text top="707" left="81" width="359" height="12" font="4">have measured speedups of 10x and more for certain benchmark</text>
<text top="722" left="81" width="54" height="12" font="4">programs.</text>
<text top="745" left="81" width="200" height="12" font="10">Categories and Subject Descriptors</text>
<text top="746" left="295" width="40" height="12" font="4">D.3.4 [</text>
<text top="746" left="334" width="105" height="12" font="11">Programming Lan-</text>
<text top="761" left="81" width="38" height="12" font="11">guages</text>
<text top="761" left="119" width="86" height="12" font="4">]: Processors —</text>
<text top="761" left="208" width="214" height="12" font="11">Incremental compilers, code generation</text>
<text top="761" left="422" width="3" height="12" font="4">.</text>
<text top="784" left="81" width="83" height="12" font="10">General Terms</text>
<text top="784" left="178" width="262" height="12" font="4">Design, Experimentation, Measurement, Perfor-</text>
<text top="799" left="81" width="38" height="12" font="4">mance.</text>
<text top="822" left="81" width="53" height="12" font="10">Keywords</text>
<text top="822" left="148" width="258" height="12" font="4">JavaScript, just-in-time compilation, trace trees.</text>
<text top="854" left="81" width="12" height="15" font="9">1.</text>
<text top="854" left="110" width="89" height="15" font="9">Introduction</text>
<text top="877" left="81" width="107" height="12" font="11">Dynamic languages</text>
<text top="877" left="191" width="249" height="12" font="4">such as JavaScript, Python, and Ruby, are pop-</text>
<text top="892" left="81" width="359" height="12" font="4">ular since they are expressive, accessible to non-experts, and make</text>
<text top="907" left="81" width="359" height="12" font="4">deployment as easy as distributing a source file. They are used for</text>
<text top="922" left="81" width="359" height="12" font="4">small scripts as well as for complex applications. JavaScript, for</text>
<text top="937" left="81" width="359" height="12" font="4">example, is the de facto standard for client-side web programming</text>
<text top="1001" left="81" width="359" height="9" font="12">Permission to make digital or hard copies of all or part of this work for personal or</text>
<text top="1013" left="81" width="359" height="9" font="12">classroom use is granted without fee provided that copies are not made or distributed</text>
<text top="1025" left="81" width="359" height="9" font="12">for profit or commercial advantage and that copies bear this notice and the full citation</text>
<text top="1037" left="81" width="359" height="9" font="12">on the first page. To copy otherwise, to republish, to post on servers or to redistribute</text>
<text top="1049" left="81" width="227" height="9" font="12">to lists, requires prior specific permission and/or a fee.</text>
<text top="1064" left="81" width="40" height="9" font="13">PLDI’09,</text>
<text top="1064" left="131" width="146" height="9" font="12">June 15–20, 2009, Dublin, Ireland.</text>
<text top="1076" left="81" width="53" height="9" font="12">Copyright c</text>
<text top="1075" left="126" width="12" height="10" font="14"></text>
<text top="1076" left="140" width="194" height="9" font="12">2009 ACM 978-1-60558-392-1/09/06. . . $5.00</text>
<text top="507" left="476" width="359" height="12" font="4">and is used for the application logic of browser-based productivity</text>
<text top="522" left="476" width="359" height="12" font="4">applications such as Google Mail, Google Docs and Zimbra Col-</text>
<text top="537" left="476" width="359" height="12" font="4">laboration Suite. In this domain, in order to provide a fluid user</text>
<text top="552" left="476" width="359" height="12" font="4">experience and enable a new generation of applications, virtual ma-</text>
<text top="567" left="476" width="333" height="12" font="4">chines must provide a low startup time and high performance.</text>
<text top="582" left="493" width="341" height="12" font="4">Compilers for statically typed languages rely on type informa-</text>
<text top="597" left="476" width="359" height="12" font="4">tion to generate efficient machine code. In a dynamically typed pro-</text>
<text top="612" left="476" width="359" height="12" font="4">gramming language such as JavaScript, the types of expressions</text>
<text top="627" left="476" width="359" height="12" font="4">may vary at runtime. This means that the compiler can no longer</text>
<text top="642" left="476" width="359" height="12" font="4">easily transform operations into machine instructions that operate</text>
<text top="656" left="476" width="359" height="12" font="4">on one specific type. Without exact type information, the compiler</text>
<text top="671" left="476" width="359" height="12" font="4">must emit slower generalized machine code that can deal with all</text>
<text top="686" left="476" width="359" height="12" font="4">potential type combinations. While compile-time static type infer-</text>
<text top="701" left="476" width="359" height="12" font="4">ence might be able to gather type information to generate opti-</text>
<text top="716" left="476" width="359" height="12" font="4">mized machine code, traditional static analysis is very expensive</text>
<text top="731" left="476" width="359" height="12" font="4">and hence not well suited for the highly interactive environment of</text>
<text top="746" left="476" width="81" height="12" font="4">a web browser.</text>
<text top="761" left="493" width="341" height="12" font="4">We present a trace-based compilation technique for dynamic</text>
<text top="776" left="476" width="359" height="12" font="4">languages that reconciles speed of compilation with excellent per-</text>
<text top="791" left="476" width="359" height="12" font="4">formance of the generated machine code. Our system uses a mixed-</text>
<text top="806" left="476" width="359" height="12" font="4">mode execution approach: the system starts running JavaScript in a</text>
<text top="821" left="476" width="359" height="12" font="4">fast-starting bytecode interpreter. As the program runs, the system</text>
<text top="836" left="476" width="49" height="12" font="4">identifies</text>
<text top="836" left="531" width="17" height="12" font="11">hot</text>
<text top="836" left="554" width="280" height="12" font="4">(frequently executed) bytecode sequences, records</text>
<text top="851" left="476" width="359" height="12" font="4">them, and compiles them to fast native code. We call such a se-</text>
<text top="866" left="476" width="128" height="12" font="4">quence of instructions a</text>
<text top="866" left="607" width="27" height="12" font="11">trace</text>
<text top="866" left="634" width="3" height="12" font="4">.</text>
<text top="881" left="493" width="341" height="12" font="4">Unlike method-based dynamic compilers, our dynamic com-</text>
<text top="896" left="476" width="359" height="12" font="4">piler operates at the granularity of individual loops. This design</text>
<text top="911" left="476" width="359" height="12" font="4">choice is based on the expectation that programs spend most of</text>
<text top="925" left="476" width="359" height="12" font="4">their time in hot loops. Even in dynamically typed languages, we</text>
<text top="940" left="476" width="156" height="12" font="4">expect hot loops to be mostly</text>
<text top="941" left="634" width="59" height="12" font="11">type-stable</text>
<text top="940" left="693" width="141" height="12" font="4">, meaning that the types of</text>
<text top="955" left="476" width="359" height="12" font="4">values are invariant. (12) For example, we would expect loop coun-</text>
<text top="970" left="476" width="359" height="12" font="4">ters that start as integers to remain integers for all iterations. When</text>
<text top="985" left="476" width="359" height="12" font="4">both of these expectations hold, a trace-based compiler can cover</text>
<text top="1000" left="476" width="359" height="12" font="4">the program execution with a small number of type-specialized, ef-</text>
<text top="1015" left="476" width="136" height="12" font="4">ficiently compiled traces.</text>
<text top="1030" left="493" width="341" height="12" font="4">Each compiled trace covers one path through the program with</text>
<text top="1045" left="476" width="359" height="12" font="4">one mapping of values to types. When the VM executes a compiled</text>
<text top="1060" left="476" width="359" height="12" font="4">trace, it cannot guarantee that the same path will be followed</text>
<text top="1075" left="476" width="359" height="12" font="4">or that the same types will occur in subsequent loop iterations.</text>
</page>
<page number="2" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="15" size="13" family="TACTGM+NimbusRomNo9L-Medi" color="#000000"/>
	<fontspec id="16" size="8" family="TIVRUK+Helvetica" color="#000000"/>
	<fontspec id="17" size="8" family="RBFYGC+Helvetica" color="#000000"/>
<text top="111" left="81" width="209" height="12" font="4">Hence, recording and compiling a trace</text>
<text top="111" left="293" width="56" height="12" font="11">speculates</text>
<text top="111" left="352" width="88" height="12" font="4">that the path and</text>
<text top="126" left="81" width="359" height="12" font="4">typing will be exactly as they were during recording for subsequent</text>
<text top="141" left="81" width="115" height="12" font="4">iterations of the loop.</text>
<text top="156" left="99" width="202" height="12" font="4">Every compiled trace contains all the</text>
<text top="156" left="305" width="37" height="12" font="11">guards</text>
<text top="156" left="345" width="94" height="12" font="4">(checks) required</text>
<text top="171" left="81" width="359" height="12" font="4">to validate the speculation. If one of the guards fails (if control</text>
<text top="186" left="81" width="359" height="12" font="4">flow is different, or a value of a different type is generated), the</text>
<text top="201" left="81" width="316" height="12" font="4">trace exits. If an exit becomes hot, the VM can record a</text>
<text top="201" left="402" width="38" height="12" font="11">branch</text>
<text top="216" left="81" width="27" height="12" font="11">trace</text>
<text top="215" left="112" width="328" height="12" font="4">starting at the exit to cover the new path. In this way, the VM</text>
<text top="230" left="81" width="49" height="12" font="4">records a</text>
<text top="231" left="133" width="51" height="12" font="11">trace tree</text>
<text top="230" left="188" width="231" height="12" font="4">covering all the hot paths through the loop.</text>
<text top="245" left="99" width="341" height="12" font="4">Nested loops can be difficult to optimize for tracing VMs. In</text>
<text top="260" left="81" width="359" height="12" font="4">a na¨ıve implementation, inner loops would become hot first, and</text>
<text top="275" left="81" width="359" height="12" font="4">the VM would start tracing there. When the inner loop exits, the</text>
<text top="290" left="81" width="359" height="12" font="4">VM would detect that a different branch was taken. The VM would</text>
<text top="305" left="81" width="359" height="12" font="4">try to record a branch trace, and find that the trace reaches not the</text>
<text top="320" left="81" width="359" height="12" font="4">inner loop header, but the outer loop header. At this point, the VM</text>
<text top="335" left="81" width="359" height="12" font="4">could continue tracing until it reaches the inner loop header again,</text>
<text top="350" left="81" width="359" height="12" font="4">thus tracing the outer loop inside a trace tree for the inner loop.</text>
<text top="365" left="81" width="359" height="12" font="4">But this requires tracing a copy of the outer loop for every side exit</text>
<text top="380" left="81" width="359" height="12" font="4">and type combination in the inner loop. In essence, this is a form</text>
<text top="395" left="81" width="359" height="12" font="4">of unintended tail duplication, which can easily overflow the code</text>
<text top="410" left="81" width="359" height="12" font="4">cache. Alternatively, the VM could simply stop tracing, and give up</text>
<text top="425" left="81" width="147" height="12" font="4">on ever tracing outer loops.</text>
<text top="440" left="99" width="268" height="12" font="4">We solve the nested loop problem by recording</text>
<text top="440" left="372" width="67" height="12" font="11">nested trace</text>
<text top="455" left="81" width="26" height="12" font="11">trees</text>
<text top="455" left="107" width="333" height="12" font="4">. Our system traces the inner loop exactly as the na¨ıve version.</text>
<text top="469" left="81" width="359" height="12" font="4">The system stops extending the inner tree when it reaches an outer</text>
<text top="484" left="81" width="359" height="12" font="4">loop, but then it starts a new trace at the outer loop header. When</text>
<text top="499" left="81" width="359" height="12" font="4">the outer loop reaches the inner loop header, the system tries to call</text>
<text top="514" left="81" width="359" height="12" font="4">the trace tree for the inner loop. If the call succeeds, the VM records</text>
<text top="529" left="81" width="359" height="12" font="4">the call to the inner tree as part of the outer trace and finishes</text>
<text top="544" left="81" width="359" height="12" font="4">the outer trace as normal. In this way, our system can trace any</text>
<text top="559" left="81" width="359" height="12" font="4">number of loops nested to any depth without causing excessive tail</text>
<text top="574" left="81" width="64" height="12" font="4">duplication.</text>
<text top="589" left="99" width="341" height="12" font="4">These techniques allow a VM to dynamically translate a pro-</text>
<text top="604" left="81" width="359" height="12" font="4">gram to nested, type-specialized trace trees. Because traces can</text>
<text top="619" left="81" width="359" height="12" font="4">cross function call boundaries, our techniques also achieve the ef-</text>
<text top="634" left="81" width="359" height="12" font="4">fects of inlining. Because traces have no internal control-flow joins,</text>
<text top="649" left="81" width="359" height="12" font="4">they can be optimized in linear time by a simple compiler (10).</text>
<text top="664" left="81" width="359" height="12" font="4">Thus, our tracing VM efficiently performs the same kind of op-</text>
<text top="679" left="81" width="359" height="12" font="4">timizations that would require interprocedural analysis in a static</text>
<text top="694" left="81" width="359" height="12" font="4">optimization setting. This makes tracing an attractive and effective</text>
<text top="709" left="81" width="324" height="12" font="4">tool to type specialize even complex function call-rich code.</text>
<text top="724" left="99" width="341" height="12" font="4">We implemented these techniques for an existing JavaScript in-</text>
<text top="738" left="81" width="320" height="12" font="4">terpreter, SpiderMonkey. We call the resulting tracing VM</text>
<text top="739" left="405" width="35" height="12" font="11">Trace-</text>
<text top="754" left="81" width="42" height="12" font="11">Monkey</text>
<text top="753" left="123" width="317" height="12" font="4">. TraceMonkey supports all the JavaScript features of Spi-</text>
<text top="768" left="81" width="318" height="12" font="4">derMonkey, with a 2x-20x speedup for traceable programs.</text>
<text top="783" left="99" width="248" height="12" font="4">This paper makes the following contributions:</text>
<text top="811" left="89" width="6" height="11" font="2">•</text>
<text top="812" left="100" width="339" height="12" font="4">We explain an algorithm for dynamically forming trace trees to</text>
<text top="827" left="100" width="339" height="12" font="4">cover a program, representing nested loops as nested trace trees.</text>
<text top="846" left="89" width="6" height="11" font="2">•</text>
<text top="848" left="100" width="355" height="12" font="4">We explain how to speculatively generate efficient type-specialized</text>
<text top="863" left="100" width="268" height="12" font="4">code for traces from dynamic language programs.</text>
<text top="882" left="89" width="6" height="11" font="2">•</text>
<text top="883" left="100" width="339" height="12" font="4">We validate our tracing techniques in an implementation based</text>
<text top="898" left="100" width="339" height="12" font="4">on the SpiderMonkey JavaScript interpreter, achieving 2x-20x</text>
<text top="913" left="100" width="157" height="12" font="4">speedups on many programs.</text>
<text top="942" left="99" width="341" height="12" font="4">The remainder of this paper is organized as follows. Section 3 is</text>
<text top="957" left="81" width="359" height="12" font="4">a general overview of trace tree based compilation we use to cap-</text>
<text top="972" left="81" width="359" height="12" font="4">ture and compile frequently executed code regions. In Section 4</text>
<text top="987" left="81" width="359" height="12" font="4">we describe our approach of covering nested loops using a num-</text>
<text top="1001" left="81" width="359" height="12" font="4">ber of individual trace trees. In Section 5 we describe our trace-</text>
<text top="1016" left="81" width="359" height="12" font="4">compilation based speculative type specialization approach we use</text>
<text top="1031" left="81" width="359" height="12" font="4">to generate efficient machine code from recorded bytecode traces.</text>
<text top="1046" left="81" width="359" height="12" font="4">Our implementation of a dynamic type-specializing compiler for</text>
<text top="1061" left="81" width="359" height="12" font="4">JavaScript is described in Section 6. Related work is discussed in</text>
<text top="1076" left="81" width="359" height="12" font="4">Section 8. In Section 7 we evaluate our dynamic compiler based on</text>
<text top="109" left="476" width="233" height="11" font="7">1 for (var i = 2; i &lt; 100; ++i) {</text>
<text top="124" left="476" width="7" height="11" font="7">2</text>
<text top="124" left="504" width="106" height="11" font="7">if (!primes[i])</text>
<text top="139" left="476" width="7" height="11" font="7">3</text>
<text top="139" left="518" width="64" height="11" font="7">continue;</text>
<text top="154" left="476" width="7" height="11" font="7">4</text>
<text top="154" left="504" width="254" height="11" font="7">for (var k = i + i; i &lt; 100; k += i)</text>
<text top="169" left="476" width="7" height="11" font="7">5</text>
<text top="169" left="518" width="127" height="11" font="7">primes[k] = false;</text>
<text top="184" left="476" width="21" height="11" font="7">6 }</text>
<text top="216" left="476" width="296" height="12" font="15">Figure 1. Sample program: sieve of Eratosthenes.</text>
<text top="217" left="777" width="42" height="11" font="7">primes</text>
<text top="216" left="825" width="9" height="12" font="4">is</text>
<text top="231" left="476" width="160" height="12" font="4">initialized to an array of 100</text>
<text top="232" left="640" width="35" height="11" font="7">false</text>
<text top="231" left="680" width="154" height="12" font="4">values on entry to this code</text>
<text top="246" left="476" width="42" height="12" font="4">snippet.</text>
<text top="318" left="608" width="31" height="8" font="16"><b>Interpret</b></text>
<text top="318" left="640" width="2" height="8" font="17"> </text>
<text top="327" left="606" width="36" height="8" font="17">Bytecodes</text>
<text top="387" left="610" width="28" height="8" font="16"><b>Monitor</b></text>
<text top="387" left="638" width="2" height="8" font="17"> </text>
<text top="412" left="506" width="27" height="8" font="16"><b>Record</b></text>
<text top="421" left="503" width="34" height="8" font="17">LIR Trace</text>
<text top="471" left="710" width="30" height="8" font="16"><b>Execute</b></text>
<text top="471" left="740" width="2" height="8" font="17"> </text>
<text top="480" left="698" width="54" height="8" font="17">Compiled Trace</text>
<text top="412" left="715" width="20" height="8" font="16"><b>Enter</b></text>
<text top="412" left="735" width="2" height="8" font="17"> </text>
<text top="421" left="698" width="54" height="8" font="17">Compiled Trace</text>
<text top="471" left="504" width="31" height="8" font="16"><b>Compile</b></text>
<text top="480" left="503" width="34" height="8" font="17">LIR Trace</text>
<text top="531" left="714" width="22" height="8" font="16"><b>Leave</b></text>
<text top="531" left="736" width="2" height="8" font="17"> </text>
<text top="540" left="698" width="54" height="8" font="17">Compiled Trace</text>
<text top="348" left="604" width="17" height="8" font="17">loop </text>
<text top="357" left="602" width="17" height="8" font="17">edge</text>
<text top="407" left="576" width="11" height="8" font="17">hot</text>
<text top="416" left="567" width="29" height="8" font="17">loop/exit</text>
<text top="384" left="503" width="20" height="8" font="17">abort </text>
<text top="393" left="496" width="32" height="8" font="17">recording</text>
<text top="436" left="530" width="29" height="8" font="17">finish at </text>
<text top="445" left="523" width="41" height="8" font="17">loop header</text>
<text top="356" left="662" width="53" height="8" font="17">cold/blacklisted</text>
<text top="365" left="674" width="29" height="8" font="17">loop/exit</text>
<text top="387" left="666" width="53" height="8" font="17">compiled trace </text>
<text top="396" left="682" width="19" height="8" font="17">ready</text>
<text top="444" left="638" width="52" height="8" font="17">loop edge with </text>
<text top="453" left="643" width="40" height="8" font="17">same types</text>
<text top="515" left="778" width="39" height="8" font="17">side exit to </text>
<text top="524" left="774" width="46" height="8" font="17">existing trace</text>
<text top="511" left="641" width="31" height="8" font="17">side exit,</text>
<text top="520" left="628" width="56" height="8" font="17">no existing trace</text>
<text top="325" left="761" width="36" height="8" font="17">Overhead </text>
<text top="344" left="758" width="39" height="8" font="17">Interpreting</text>
<text top="363" left="767" width="22" height="8" font="17">Native</text>
<text top="308" left="757" width="44" height="8" font="16"><b>Symbol Key</b></text>
<text top="589" left="476" width="52" height="12" font="15">Figure 2.</text>
<text top="589" left="534" width="300" height="12" font="4">State machine describing the major activities of Trace-</text>
<text top="604" left="476" width="359" height="12" font="4">Monkey and the conditions that cause transitions to a new activ-</text>
<text top="619" left="476" width="359" height="12" font="4">ity. In the dark box, TM executes JS as compiled traces. In the</text>
<text top="634" left="476" width="359" height="12" font="4">light gray boxes, TM executes JS in the standard interpreter. White</text>
<text top="649" left="476" width="359" height="12" font="4">boxes are overhead. Thus, to maximize performance, we need to</text>
<text top="664" left="476" width="359" height="12" font="4">maximize time spent in the darkest box and minimize time spent in</text>
<text top="679" left="476" width="359" height="12" font="4">the white boxes. The best case is a loop where the types at the loop</text>
<text top="694" left="476" width="359" height="12" font="4">edge are the same as the types on entry–then TM can stay in native</text>
<text top="708" left="476" width="146" height="12" font="4">code until the loop is done.</text>
<text top="751" left="476" width="359" height="12" font="4">a set of industry benchmarks. The paper ends with conclusions in</text>
<text top="766" left="476" width="359" height="12" font="4">Section 9 and an outlook on future work is presented in Section 10.</text>
<text top="799" left="476" width="12" height="15" font="9">2.</text>
<text top="799" left="504" width="232" height="15" font="9">Overview: Example Tracing Run</text>
<text top="822" left="476" width="359" height="12" font="4">This section provides an overview of our system by describing</text>
<text top="837" left="476" width="359" height="12" font="4">how TraceMonkey executes an example program. The example</text>
<text top="852" left="476" width="359" height="12" font="4">program, shown in Figure 1, computes the first 100 prime numbers</text>
<text top="867" left="476" width="359" height="12" font="4">with nested loops. The narrative should be read along with Figure 2,</text>
<text top="882" left="476" width="359" height="12" font="4">which describes the activities TraceMonkey performs and when it</text>
<text top="897" left="476" width="160" height="12" font="4">transitions between the loops.</text>
<text top="912" left="493" width="341" height="12" font="4">TraceMonkey always begins executing a program in the byte-</text>
<text top="927" left="476" width="359" height="12" font="4">code interpreter. Every loop back edge is a potential trace point.</text>
<text top="942" left="476" width="359" height="12" font="4">When the interpreter crosses a loop edge, TraceMonkey invokes</text>
<text top="957" left="476" width="16" height="12" font="4">the</text>
<text top="957" left="496" width="74" height="12" font="11">trace monitor</text>
<text top="957" left="570" width="264" height="12" font="4">, which may decide to record or execute a native</text>
<text top="972" left="476" width="359" height="12" font="4">trace. At the start of execution, there are no compiled traces yet, so</text>
<text top="987" left="476" width="359" height="12" font="4">the trace monitor counts the number of times each loop back edge is</text>
<text top="1001" left="476" width="161" height="12" font="4">executed until a loop becomes</text>
<text top="1002" left="639" width="17" height="12" font="11">hot</text>
<text top="1001" left="657" width="178" height="12" font="4">, currently after 2 crossings. Note</text>
<text top="1016" left="476" width="359" height="12" font="4">that the way our loops are compiled, the loop edge is crossed before</text>
<text top="1031" left="476" width="359" height="12" font="4">entering the loop, so the second crossing occurs immediately after</text>
<text top="1046" left="476" width="92" height="12" font="4">the first iteration.</text>
<text top="1061" left="493" width="341" height="12" font="4">Here is the sequence of events broken down by outer loop</text>
<text top="1076" left="476" width="49" height="12" font="4">iteration:</text>
</page>
<page number="3" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="18" size="13" family="AZLOMJ+CMMI9" color="#000000"/>
<text top="109" left="81" width="134" height="11" font="7">v0 := ld state[748]</text>
<text top="109" left="250" width="332" height="11" font="7">// load primes from the trace activation record</text>
<text top="124" left="123" width="85" height="11" font="7">st sp[0], v0</text>
<text top="124" left="250" width="254" height="11" font="7">// store primes to interpreter stack</text>
<text top="139" left="81" width="134" height="11" font="7">v1 := ld state[764]</text>
<text top="139" left="250" width="297" height="11" font="7">// load k from the trace activation record</text>
<text top="154" left="81" width="92" height="11" font="7">v2 := i2f(v1)</text>
<text top="154" left="250" width="219" height="11" font="7">// convert k from int to double</text>
<text top="169" left="123" width="85" height="11" font="7">st sp[8], v1</text>
<text top="169" left="250" width="219" height="11" font="7">// store k to interpreter stack</text>
<text top="184" left="123" width="85" height="11" font="7">st sp[16], 0</text>
<text top="184" left="250" width="247" height="11" font="7">// store false to interpreter stack</text>
<text top="199" left="81" width="99" height="11" font="7">v3 := ld v0[4]</text>
<text top="199" left="250" width="205" height="11" font="7">// load class word for primes</text>
<text top="214" left="81" width="113" height="11" font="7">v4 := and v3, -4</text>
<text top="214" left="250" width="275" height="11" font="7">// mask out object class tag for primes</text>
<text top="229" left="81" width="127" height="11" font="7">v5 := eq v4, Array</text>
<text top="229" left="250" width="240" height="11" font="7">// test whether primes is an array</text>
<text top="244" left="123" width="35" height="11" font="7">xf v5</text>
<text top="244" left="250" width="191" height="11" font="7">// side exit if v5 is false</text>
<text top="259" left="81" width="233" height="11" font="7">v6 := js_Array_set(v0, v2, false)</text>
<text top="259" left="328" width="261" height="11" font="7">// call function to set array element</text>
<text top="274" left="81" width="99" height="11" font="7">v7 := eq v6, 0</text>
<text top="274" left="250" width="212" height="11" font="7">// test return value from call</text>
<text top="288" left="123" width="35" height="11" font="7">xt v7</text>
<text top="288" left="250" width="304" height="11" font="7">// side exit if js_Array_set returns false.</text>
<text top="323" left="81" width="255" height="12" font="15">Figure 3. LIR snippet for sample program.</text>
<text top="323" left="341" width="493" height="12" font="4">This is the LIR recorded for line 5 of the sample program in Figure 1. The LIR encodes</text>
<text top="338" left="81" width="753" height="12" font="4">the semantics in SSA form using temporary variables. The LIR also encodes all the stores that the interpreter would do to its data stack.</text>
<text top="353" left="81" width="753" height="12" font="4">Sometimes these stores can be optimized away as the stack locations are live only on exits to the interpreter. Finally, the LIR records guards</text>
<text top="368" left="81" width="363" height="12" font="4">and side exits to verify the assumptions made in this recording: that</text>
<text top="368" left="447" width="42" height="11" font="7">primes</text>
<text top="368" left="493" width="294" height="12" font="4">is an array and that the call to set its element succeeds.</text>
<text top="408" left="81" width="120" height="11" font="7">mov edx, ebx(748)</text>
<text top="408" left="243" width="332" height="11" font="7">// load primes from the trace activation record</text>
<text top="423" left="81" width="106" height="11" font="7">mov edi(0), edx</text>
<text top="423" left="243" width="282" height="11" font="7">// (*) store primes to interpreter stack</text>
<text top="438" left="81" width="120" height="11" font="7">mov esi, ebx(764)</text>
<text top="438" left="243" width="297" height="11" font="7">// load k from the trace activation record</text>
<text top="453" left="81" width="106" height="11" font="7">mov edi(8), esi</text>
<text top="453" left="243" width="247" height="11" font="7">// (*) store k to interpreter stack</text>
<text top="467" left="81" width="99" height="11" font="7">mov edi(16), 0</text>
<text top="467" left="243" width="275" height="11" font="7">// (*) store false to interpreter stack</text>
<text top="482" left="81" width="106" height="11" font="7">mov eax, edx(4)</text>
<text top="482" left="243" width="282" height="11" font="7">// (*) load object class word for primes</text>
<text top="497" left="81" width="78" height="11" font="7">and eax, -4</text>
<text top="497" left="243" width="304" height="11" font="7">// (*) mask out object class tag for primes</text>
<text top="512" left="81" width="99" height="11" font="7">cmp eax, Array</text>
<text top="512" left="243" width="268" height="11" font="7">// (*) test whether primes is an array</text>
<text top="527" left="81" width="106" height="11" font="7">jne side_exit_1</text>
<text top="527" left="243" width="297" height="11" font="7">// (*) side exit if primes is not an array</text>
<text top="542" left="81" width="71" height="11" font="7">sub esp, 8</text>
<text top="542" left="243" width="304" height="11" font="7">// bump stack for call alignment convention</text>
<text top="557" left="81" width="71" height="11" font="7">push false</text>
<text top="557" left="243" width="212" height="11" font="7">// push last argument for call</text>
<text top="572" left="81" width="56" height="11" font="7">push esi</text>
<text top="572" left="243" width="219" height="11" font="7">// push first argument for call</text>
<text top="587" left="81" width="120" height="11" font="7">call js_Array_set</text>
<text top="587" left="243" width="261" height="11" font="7">// call function to set array element</text>
<text top="602" left="81" width="71" height="11" font="7">add esp, 8</text>
<text top="602" left="243" width="205" height="11" font="7">// clean up extra stack space</text>
<text top="617" left="81" width="85" height="11" font="7">mov ecx, ebx</text>
<text top="617" left="243" width="254" height="11" font="7">// (*) created by register allocator</text>
<text top="632" left="81" width="92" height="11" font="7">test eax, eax</text>
<text top="632" left="243" width="282" height="11" font="7">// (*) test return value of js_Array_set</text>
<text top="647" left="81" width="99" height="11" font="7">je side_exit_2</text>
<text top="647" left="243" width="219" height="11" font="7">// (*) side exit if call failed</text>
<text top="662" left="81" width="21" height="11" font="7">...</text>
<text top="677" left="81" width="85" height="11" font="7">side_exit_1:</text>
<text top="692" left="81" width="113" height="11" font="7">mov ecx, ebp(-4)</text>
<text top="692" left="243" width="99" height="11" font="7">// restore ecx</text>
<text top="707" left="81" width="85" height="11" font="7">mov esp, ebp</text>
<text top="707" left="243" width="99" height="11" font="7">// restore esp</text>
<text top="721" left="81" width="71" height="11" font="7">jmp epilog</text>
<text top="721" left="243" width="169" height="11" font="7">// jump to ret statement</text>
<text top="756" left="81" width="243" height="12" font="15">Figure 4. x86 snippet for sample program.</text>
<text top="756" left="327" width="507" height="12" font="4">This is the x86 code compiled from the LIR snippet in Figure 3. Most LIR instructions compile</text>
<text top="771" left="81" width="286" height="12" font="4">to a single x86 instruction. Instructions marked with</text>
<text top="772" left="371" width="21" height="11" font="7">(*)</text>
<text top="771" left="397" width="438" height="12" font="4">would be omitted by an idealized compiler that knew that none of the side exits</text>
<text top="786" left="81" width="753" height="12" font="4">would ever be taken. The 17 instructions generated by the compiler compare favorably with the 100+ instructions that the interpreter would</text>
<text top="801" left="81" width="333" height="12" font="4">execute for the same code snippet, including 4 indirect jumps.</text>
<text top="845" left="99" width="21" height="12" font="15">i=2.</text>
<text top="845" left="126" width="314" height="12" font="4">This is the first iteration of the outer loop. The loop on</text>
<text top="860" left="81" width="359" height="12" font="4">lines 4-5 becomes hot on its second iteration, so TraceMonkey en-</text>
<text top="875" left="81" width="359" height="12" font="4">ters recording mode on line 4. In recording mode, TraceMonkey</text>
<text top="890" left="81" width="359" height="12" font="4">records the code along the trace in a low-level compiler intermedi-</text>
<text top="905" left="81" width="137" height="12" font="4">ate representation we call</text>
<text top="905" left="222" width="20" height="12" font="11">LIR</text>
<text top="905" left="242" width="198" height="12" font="4">. The LIR trace encodes all the oper-</text>
<text top="920" left="81" width="359" height="12" font="4">ations performed and the types of all operands. The LIR trace also</text>
<text top="935" left="81" width="43" height="12" font="4">encodes</text>
<text top="935" left="128" width="37" height="12" font="11">guards</text>
<text top="935" left="165" width="275" height="12" font="4">, which are checks that verify that the control flow</text>
<text top="950" left="81" width="359" height="12" font="4">and types are identical to those observed during trace recording.</text>
<text top="965" left="81" width="359" height="12" font="4">Thus, on later executions, if and only if all guards are passed, the</text>
<text top="980" left="81" width="224" height="12" font="4">trace has the required program semantics.</text>
<text top="995" left="99" width="341" height="12" font="4">TraceMonkey stops recording when execution returns to the</text>
<text top="1010" left="81" width="359" height="12" font="4">loop header or exits the loop. In this case, execution returns to the</text>
<text top="1025" left="81" width="117" height="12" font="4">loop header on line 4.</text>
<text top="1040" left="99" width="341" height="12" font="4">After recording is finished, TraceMonkey compiles the trace to</text>
<text top="1055" left="81" width="359" height="12" font="4">native code using the recorded type information for optimization.</text>
<text top="1070" left="81" width="359" height="12" font="4">The result is a native code fragment that can be entered if the</text>
<text top="845" left="476" width="359" height="12" font="4">interpreter PC and the types of values match those observed when</text>
<text top="860" left="476" width="330" height="12" font="4">trace recording was started. The first trace in our example,</text>
<text top="860" left="811" width="8" height="12" font="18">T</text>
<text top="865" left="819" width="11" height="8" font="8">45</text>
<text top="860" left="831" width="3" height="12" font="4">,</text>
<text top="875" left="476" width="359" height="12" font="4">covers lines 4 and 5. This trace can be entered if the PC is at line 4,</text>
<text top="891" left="476" width="7" height="11" font="7">i</text>
<text top="890" left="486" width="19" height="12" font="4">and</text>
<text top="891" left="508" width="7" height="11" font="7">k</text>
<text top="890" left="518" width="88" height="12" font="4">are integers, and</text>
<text top="891" left="609" width="42" height="11" font="7">primes</text>
<text top="890" left="655" width="153" height="12" font="4">is an object. After compiling</text>
<text top="890" left="811" width="8" height="12" font="18">T</text>
<text top="895" left="819" width="11" height="8" font="8">45</text>
<text top="890" left="831" width="3" height="12" font="4">,</text>
<text top="905" left="476" width="343" height="12" font="4">TraceMonkey returns to the interpreter and loops back to line 1.</text>
<text top="920" left="493" width="21" height="12" font="15">i=3.</text>
<text top="920" left="519" width="315" height="12" font="4">Now the loop header at line 1 has become hot, so Trace-</text>
<text top="935" left="476" width="359" height="12" font="4">Monkey starts recording. When recording reaches line 4, Trace-</text>
<text top="950" left="476" width="359" height="12" font="4">Monkey observes that it has reached an inner loop header that al-</text>
<text top="965" left="476" width="359" height="12" font="4">ready has a compiled trace, so TraceMonkey attempts to nest the</text>
<text top="980" left="476" width="359" height="12" font="4">inner loop inside the current trace. The first step is to call the inner</text>
<text top="995" left="476" width="359" height="12" font="4">trace as a subroutine. This executes the loop on line 4 to completion</text>
<text top="1010" left="476" width="359" height="12" font="4">and then returns to the recorder. TraceMonkey verifies that the call</text>
<text top="1025" left="476" width="359" height="12" font="4">was successful and then records the call to the inner trace as part of</text>
<text top="1040" left="476" width="359" height="12" font="4">the current trace. Recording continues until execution reaches line</text>
<text top="1055" left="476" width="359" height="12" font="4">1, and at which point TraceMonkey finishes and compiles a trace</text>
<text top="1070" left="476" width="97" height="12" font="4">for the outer loop,</text>
<text top="1069" left="576" width="8" height="12" font="18">T</text>
<text top="1074" left="584" width="11" height="8" font="8">16</text>
<text top="1070" left="596" width="3" height="12" font="4">.</text>
</page>
<page number="4" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="19" size="9" family="LNDLDG+CMMI6" color="#000000"/>
<text top="111" left="99" width="21" height="12" font="15">i=4.</text>
<text top="111" left="123" width="195" height="12" font="4">On this iteration, TraceMonkey calls</text>
<text top="111" left="322" width="8" height="12" font="18">T</text>
<text top="115" left="330" width="11" height="8" font="8">16</text>
<text top="111" left="342" width="51" height="12" font="4">. Because</text>
<text top="112" left="396" width="21" height="11" font="7">i=4</text>
<text top="111" left="417" width="23" height="12" font="4">, the</text>
<text top="127" left="81" width="14" height="11" font="7">if</text>
<text top="126" left="100" width="340" height="12" font="4">statement on line 2 is taken. This branch was not taken in the</text>
<text top="141" left="81" width="150" height="12" font="4">original trace, so this causes</text>
<text top="141" left="234" width="8" height="12" font="18">T</text>
<text top="145" left="242" width="11" height="8" font="8">16</text>
<text top="141" left="257" width="182" height="12" font="4">to fail a guard and take a side exit.</text>
<text top="156" left="81" width="359" height="12" font="4">The exit is not yet hot, so TraceMonkey returns to the interpreter,</text>
<text top="171" left="81" width="210" height="12" font="4">which executes the continue statement.</text>
<text top="185" left="99" width="21" height="12" font="15">i=5.</text>
<text top="186" left="123" width="102" height="12" font="4">TraceMonkey calls</text>
<text top="185" left="229" width="8" height="12" font="18">T</text>
<text top="190" left="237" width="11" height="8" font="8">16</text>
<text top="186" left="249" width="191" height="12" font="4">, which in turn calls the nested trace</text>
<text top="200" left="81" width="8" height="12" font="18">T</text>
<text top="205" left="89" width="11" height="8" font="8">45</text>
<text top="201" left="101" width="3" height="12" font="4">.</text>
<text top="200" left="109" width="8" height="12" font="18">T</text>
<text top="205" left="117" width="11" height="8" font="8">16</text>
<text top="201" left="133" width="306" height="12" font="4">loops back to its own header, starting the next iteration</text>
<text top="215" left="81" width="202" height="12" font="4">without ever returning to the monitor.</text>
<text top="230" left="99" width="21" height="12" font="15">i=6.</text>
<text top="230" left="124" width="316" height="12" font="4">On this iteration, the side exit on line 2 is taken again. This</text>
<text top="245" left="81" width="235" height="12" font="4">time, the side exit becomes hot, so a trace</text>
<text top="245" left="321" width="8" height="12" font="18">T</text>
<text top="250" left="329" width="11" height="8" font="8">23</text>
<text top="250" left="340" width="3" height="8" font="19">,</text>
<text top="250" left="343" width="5" height="8" font="8">1</text>
<text top="245" left="354" width="86" height="12" font="4">is recorded that</text>
<text top="260" left="81" width="327" height="12" font="4">covers line 3 and returns to the loop header. Thus, the end of</text>
<text top="260" left="411" width="8" height="12" font="18">T</text>
<text top="265" left="419" width="11" height="8" font="8">23</text>
<text top="265" left="430" width="3" height="8" font="19">,</text>
<text top="265" left="433" width="5" height="8" font="8">1</text>
<text top="275" left="81" width="156" height="12" font="4">jumps directly to the start of</text>
<text top="275" left="242" width="8" height="12" font="18">T</text>
<text top="280" left="250" width="11" height="8" font="8">16</text>
<text top="275" left="261" width="178" height="12" font="4">. The side exit is patched so that</text>
<text top="290" left="81" width="211" height="12" font="4">on future iterations, it jumps directly to</text>
<text top="290" left="295" width="8" height="12" font="18">T</text>
<text top="295" left="304" width="11" height="8" font="8">23</text>
<text top="295" left="314" width="3" height="8" font="19">,</text>
<text top="295" left="318" width="5" height="8" font="8">1</text>
<text top="290" left="324" width="3" height="12" font="4">.</text>
<text top="305" left="99" width="341" height="12" font="4">At this point, TraceMonkey has compiled enough traces to cover</text>
<text top="320" left="81" width="359" height="12" font="4">the entire nested loop structure, so the rest of the program runs</text>
<text top="335" left="81" width="123" height="12" font="4">entirely as native code.</text>
<text top="373" left="81" width="12" height="15" font="9">3.</text>
<text top="373" left="110" width="82" height="15" font="9">Trace Trees</text>
<text top="397" left="81" width="359" height="12" font="4">In this section, we describe traces, trace trees, and how they are</text>
<text top="412" left="81" width="359" height="12" font="4">formed at run time. Although our techniques apply to any dynamic</text>
<text top="426" left="81" width="359" height="12" font="4">language interpreter, we will describe them assuming a bytecode</text>
<text top="441" left="81" width="220" height="12" font="4">interpreter to keep the exposition simple.</text>
<text top="472" left="81" width="17" height="12" font="15">3.1</text>
<text top="472" left="111" width="38" height="12" font="15">Traces</text>
<text top="493" left="81" width="10" height="12" font="4">A</text>
<text top="494" left="95" width="27" height="12" font="11">trace</text>
<text top="493" left="127" width="312" height="12" font="4">is simply a program path, which may cross function call</text>
<text top="508" left="81" width="202" height="12" font="4">boundaries. TraceMonkey focuses on</text>
<text top="508" left="287" width="60" height="12" font="11">loop traces</text>
<text top="508" left="347" width="92" height="12" font="4">, that originate at</text>
<text top="523" left="81" width="359" height="12" font="4">a loop edge and represent a single iteration through the associated</text>
<text top="538" left="81" width="27" height="12" font="4">loop.</text>
<text top="553" left="99" width="341" height="12" font="4">Similar to an extended basic block, a trace is only entered at</text>
<text top="568" left="81" width="359" height="12" font="4">the top, but may have many exits. In contrast to an extended basic</text>
<text top="583" left="81" width="359" height="12" font="4">block, a trace can contain join nodes. Since a trace always only</text>
<text top="598" left="81" width="359" height="12" font="4">follows one single path through the original program, however, join</text>
<text top="613" left="81" width="359" height="12" font="4">nodes are not recognizable as such in a trace and have a single</text>
<text top="628" left="81" width="196" height="12" font="4">predecessor node like regular nodes.</text>
<text top="643" left="99" width="10" height="12" font="4">A</text>
<text top="643" left="112" width="60" height="12" font="11">typed trace</text>
<text top="643" left="175" width="264" height="12" font="4">is a trace annotated with a type for every variable</text>
<text top="658" left="81" width="359" height="12" font="4">(including temporaries) on the trace. A typed trace also has an entry</text>
<text top="673" left="81" width="50" height="12" font="11">type map</text>
<text top="673" left="135" width="305" height="12" font="4">giving the required types for variables used on the trace</text>
<text top="688" left="81" width="359" height="12" font="4">before they are defined. For example, a trace could have a type map</text>
<text top="704" left="81" width="141" height="11" font="7">(x: int, b: boolean)</text>
<text top="703" left="222" width="217" height="12" font="4">, meaning that the trace may be entered</text>
<text top="718" left="81" width="169" height="12" font="4">only if the value of the variable</text>
<text top="718" left="254" width="7" height="11" font="7">x</text>
<text top="718" left="264" width="50" height="12" font="4">is of type</text>
<text top="718" left="318" width="21" height="11" font="7">int</text>
<text top="718" left="343" width="86" height="12" font="4">and the value of</text>
<text top="718" left="433" width="7" height="11" font="7">b</text>
<text top="733" left="81" width="51" height="12" font="4">is of type</text>
<text top="733" left="135" width="49" height="11" font="7">boolean</text>
<text top="733" left="185" width="255" height="12" font="4">. The entry type map is much like the signature</text>
<text top="747" left="81" width="72" height="12" font="4">of a function.</text>
<text top="762" left="99" width="341" height="12" font="4">In this paper, we only discuss typed loop traces, and we will</text>
<text top="777" left="81" width="359" height="12" font="4">refer to them simply as “traces”. The key property of typed loop</text>
<text top="792" left="81" width="359" height="12" font="4">traces is that they can be compiled to efficient machine code using</text>
<text top="807" left="81" width="249" height="12" font="4">the same techniques used for typed languages.</text>
<text top="822" left="99" width="317" height="12" font="4">In TraceMonkey, traces are recorded in trace-flavored SSA</text>
<text top="822" left="419" width="20" height="12" font="11">LIR</text>
<text top="837" left="81" width="359" height="12" font="4">(low-level intermediate representation). In trace-flavored SSA (or</text>
<text top="852" left="81" width="359" height="12" font="4">TSSA), phi nodes appear only at the entry point, which is reached</text>
<text top="867" left="81" width="359" height="12" font="4">both on entry and via loop edges. The important LIR primitives</text>
<text top="882" left="81" width="359" height="12" font="4">are constant values, memory loads and stores (by address and</text>
<text top="897" left="81" width="359" height="12" font="4">offset), integer operators, floating-point operators, function calls,</text>
<text top="912" left="81" width="359" height="12" font="4">and conditional exits. Type conversions, such as integer to double,</text>
<text top="927" left="81" width="359" height="12" font="4">are represented by function calls. This makes the LIR used by</text>
<text top="942" left="81" width="359" height="12" font="4">TraceMonkey independent of the concrete type system and type</text>
<text top="957" left="81" width="359" height="12" font="4">conversion rules of the source language. The LIR operations are</text>
<text top="972" left="81" width="359" height="12" font="4">generic enough that the backend compiler is language independent.</text>
<text top="987" left="81" width="205" height="12" font="4">Figure 3 shows an example LIR trace.</text>
<text top="1001" left="99" width="341" height="12" font="4">Bytecode interpreters typically represent values in a various</text>
<text top="1016" left="81" width="359" height="12" font="4">complex data structures (e.g., hash tables) in a boxed format (i.e.,</text>
<text top="1031" left="81" width="359" height="12" font="4">with attached type tag bits). Since a trace is intended to represent</text>
<text top="1046" left="81" width="359" height="12" font="4">efficient code that eliminates all that complexity, our traces oper-</text>
<text top="1061" left="81" width="359" height="12" font="4">ate on unboxed values in simple variables and arrays as much as</text>
<text top="1076" left="81" width="47" height="12" font="4">possible.</text>
<text top="111" left="493" width="341" height="12" font="4">A trace records all its intermediate values in a small activation</text>
<text top="126" left="476" width="359" height="12" font="4">record area. To make variable accesses fast on trace, the trace also</text>
<text top="141" left="476" width="359" height="12" font="4">imports local and global variables by unboxing them and copying</text>
<text top="156" left="476" width="359" height="12" font="4">them to its activation record. Thus, the trace can read and write</text>
<text top="171" left="476" width="359" height="12" font="4">these variables with simple loads and stores from a native activation</text>
<text top="186" left="476" width="359" height="12" font="4">recording, independently of the boxing mechanism used by the</text>
<text top="201" left="476" width="359" height="12" font="4">interpreter. When the trace exits, the VM boxes the values from</text>
<text top="215" left="476" width="359" height="12" font="4">this native storage location and copies them back to the interpreter</text>
<text top="230" left="476" width="56" height="12" font="4">structures.</text>
<text top="245" left="493" width="341" height="12" font="4">For every control-flow branch in the source program, the</text>
<text top="260" left="476" width="359" height="12" font="4">recorder generates conditional exit LIR instructions. These instruc-</text>
<text top="275" left="476" width="359" height="12" font="4">tions exit from the trace if required control flow is different from</text>
<text top="290" left="476" width="359" height="12" font="4">what it was at trace recording, ensuring that the trace instructions</text>
<text top="305" left="476" width="359" height="12" font="4">are run only if they are supposed to. We call these instructions</text>
<text top="320" left="476" width="32" height="12" font="11">guard</text>
<text top="320" left="511" width="66" height="12" font="4">instructions.</text>
<text top="335" left="493" width="310" height="12" font="4">Most of our traces represent loops and end with the special</text>
<text top="336" left="806" width="28" height="11" font="7">loop</text>
<text top="350" left="476" width="359" height="12" font="4">LIR instruction. This is just an unconditional branch to the top of</text>
<text top="365" left="476" width="239" height="12" font="4">the trace. Such traces return only via guards.</text>
<text top="380" left="493" width="341" height="12" font="4">Now, we describe the key optimizations that are performed as</text>
<text top="395" left="476" width="359" height="12" font="4">part of recording LIR. All of these optimizations reduce complex</text>
<text top="410" left="476" width="359" height="12" font="4">dynamic language constructs to simple typed constructs by spe-</text>
<text top="425" left="476" width="359" height="12" font="4">cializing for the current trace. Each optimization requires guard in-</text>
<text top="440" left="476" width="359" height="12" font="4">structions to verify their assumptions about the state and exit the</text>
<text top="455" left="476" width="96" height="12" font="4">trace if necessary.</text>
<text top="469" left="493" width="113" height="12" font="15">Type specialization.</text>
<text top="484" left="493" width="341" height="12" font="4">All LIR primitives apply to operands of specific types. Thus,</text>
<text top="499" left="476" width="359" height="12" font="4">LIR traces are necessarily type-specialized, and a compiler can</text>
<text top="514" left="476" width="359" height="12" font="4">easily produce a translation that requires no type dispatches. A</text>
<text top="529" left="476" width="359" height="12" font="4">typical bytecode interpreter carries tag bits along with each value,</text>
<text top="544" left="476" width="359" height="12" font="4">and to perform any operation, must check the tag bits, dynamically</text>
<text top="559" left="476" width="359" height="12" font="4">dispatch, mask out the tag bits to recover the untagged value,</text>
<text top="574" left="476" width="359" height="12" font="4">perform the operation, and then reapply tags. LIR omits everything</text>
<text top="589" left="476" width="142" height="12" font="4">except the operation itself.</text>
<text top="604" left="493" width="341" height="12" font="4">A potential problem is that some operations can produce values</text>
<text top="619" left="476" width="359" height="12" font="4">of unpredictable types. For example, reading a property from an</text>
<text top="634" left="476" width="359" height="12" font="4">object could yield a value of any type, not necessarily the type</text>
<text top="649" left="476" width="359" height="12" font="4">observed during recording. The recorder emits guard instructions</text>
<text top="664" left="476" width="359" height="12" font="4">that conditionally exit if the operation yields a value of a different</text>
<text top="679" left="476" width="359" height="12" font="4">type from that seen during recording. These guard instructions</text>
<text top="694" left="476" width="359" height="12" font="4">guarantee that as long as execution is on trace, the types of values</text>
<text top="709" left="476" width="359" height="12" font="4">match those of the typed trace. When the VM observes a side exit</text>
<text top="724" left="476" width="359" height="12" font="4">along such a type guard, a new typed trace is recorded originating</text>
<text top="738" left="476" width="359" height="12" font="4">at the side exit location, capturing the new type of the operation in</text>
<text top="753" left="476" width="49" height="12" font="4">question.</text>
<text top="768" left="493" width="224" height="12" font="15">Representation specialization: objects.</text>
<text top="768" left="724" width="111" height="12" font="4">In JavaScript, name</text>
<text top="783" left="476" width="359" height="12" font="4">lookup semantics are complex and potentially expensive because</text>
<text top="798" left="476" width="258" height="12" font="4">they include features like object inheritance and</text>
<text top="799" left="737" width="28" height="11" font="7">eval</text>
<text top="798" left="766" width="68" height="12" font="4">. To evaluate</text>
<text top="813" left="476" width="216" height="12" font="4">an object property read expression like</text>
<text top="814" left="696" width="21" height="11" font="7">o.x</text>
<text top="813" left="718" width="117" height="12" font="4">, the interpreter must</text>
<text top="828" left="476" width="146" height="12" font="4">search the property map of</text>
<text top="829" left="625" width="7" height="11" font="7">o</text>
<text top="828" left="636" width="198" height="12" font="4">and all of its prototypes and parents.</text>
<text top="843" left="476" width="359" height="12" font="4">Property maps can be implemented with different data structures</text>
<text top="858" left="476" width="359" height="12" font="4">(e.g., per-object hash tables or shared hash tables), so the search</text>
<text top="873" left="476" width="359" height="12" font="4">process also must dispatch on the representation of each object</text>
<text top="888" left="476" width="359" height="12" font="4">found during search. TraceMonkey can simply observe the result of</text>
<text top="903" left="476" width="359" height="12" font="4">the search process and record the simplest possible LIR to access</text>
<text top="918" left="476" width="359" height="12" font="4">the property value. For example, the search might finds the value of</text>
<text top="934" left="476" width="21" height="11" font="7">o.x</text>
<text top="933" left="500" width="99" height="12" font="4">in the prototype of</text>
<text top="934" left="602" width="7" height="11" font="7">o</text>
<text top="933" left="609" width="225" height="12" font="4">, which uses a shared hash-table represen-</text>
<text top="948" left="476" width="91" height="12" font="4">tation that places</text>
<text top="949" left="569" width="7" height="11" font="7">x</text>
<text top="948" left="580" width="255" height="12" font="4">in slot 2 of a property vector. Then the recorded</text>
<text top="963" left="476" width="147" height="12" font="4">can generate LIR that reads</text>
<text top="964" left="625" width="21" height="11" font="7">o.x</text>
<text top="963" left="649" width="185" height="12" font="4">with just two or three loads: one to</text>
<text top="978" left="476" width="359" height="12" font="4">get the prototype, possibly one to get the property value vector, and</text>
<text top="993" left="476" width="359" height="12" font="4">one more to get slot 2 from the vector. This is a vast simplification</text>
<text top="1007" left="476" width="359" height="12" font="4">and speedup compared to the original interpreter code. Inheritance</text>
<text top="1022" left="476" width="359" height="12" font="4">relationships and object representations can change during execu-</text>
<text top="1037" left="476" width="359" height="12" font="4">tion, so the simplified code requires guard instructions that ensure</text>
<text top="1052" left="476" width="359" height="12" font="4">the object representation is the same. In TraceMonkey, objects’ rep-</text>
</page>
<page number="5" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="20" size="9" family="KUYGUP+NimbusRomNo9L-Regu" color="#000000"/>
	<fontspec id="21" size="12" family="KUYGUP+NimbusRomNo9L-Regu" color="#000000"/>
<text top="111" left="81" width="281" height="12" font="4">resentations are assigned an integer key called the</text>
<text top="111" left="367" width="69" height="12" font="11">object shape</text>
<text top="111" left="436" width="3" height="12" font="4">.</text>
<text top="126" left="81" width="337" height="12" font="4">Thus, the guard is a simple equality check on the object shape.</text>
<text top="141" left="99" width="236" height="12" font="15">Representation specialization: numbers.</text>
<text top="141" left="341" width="99" height="12" font="4">JavaScript has no</text>
<text top="156" left="81" width="359" height="12" font="4">integer type, only a Number type that is the set of 64-bit IEEE-</text>
<text top="171" left="81" width="359" height="12" font="4">754 floating-pointer numbers (“doubles”). But many JavaScript</text>
<text top="186" left="81" width="359" height="12" font="4">operators, in particular array accesses and bitwise operators, really</text>
<text top="201" left="81" width="359" height="12" font="4">operate on integers, so they first convert the number to an integer,</text>
<text top="216" left="81" width="295" height="12" font="4">and then convert any integer result back to a double.</text>
<text top="213" left="376" width="4" height="8" font="20">1</text>
<text top="216" left="387" width="53" height="12" font="4">Clearly, a</text>
<text top="231" left="81" width="359" height="12" font="4">JavaScript VM that wants to be fast must find a way to operate on</text>
<text top="246" left="81" width="244" height="12" font="4">integers directly and avoid these conversions.</text>
<text top="261" left="99" width="341" height="12" font="4">In TraceMonkey, we support two representations for numbers:</text>
<text top="276" left="81" width="359" height="12" font="4">integers and doubles. The interpreter uses integer representations</text>
<text top="291" left="81" width="359" height="12" font="4">as much as it can, switching for results that can only be represented</text>
<text top="306" left="81" width="359" height="12" font="4">as doubles. When a trace is started, some values may be imported</text>
<text top="321" left="81" width="359" height="12" font="4">and represented as integers. Some operations on integers require</text>
<text top="336" left="81" width="359" height="12" font="4">guards. For example, adding two integers can produce a value too</text>
<text top="350" left="81" width="189" height="12" font="4">large for the integer representation.</text>
<text top="365" left="99" width="104" height="12" font="15">Function inlining.</text>
<text top="365" left="209" width="231" height="12" font="4">LIR traces can cross function boundaries</text>
<text top="380" left="81" width="359" height="12" font="4">in either direction, achieving function inlining. Move instructions</text>
<text top="395" left="81" width="359" height="12" font="4">need to be recorded for function entry and exit to copy arguments</text>
<text top="410" left="81" width="359" height="12" font="4">in and return values out. These move statements are then optimized</text>
<text top="425" left="81" width="359" height="12" font="4">away by the compiler using copy propagation. In order to be able</text>
<text top="440" left="81" width="359" height="12" font="4">to return to the interpreter, the trace must also generate LIR to</text>
<text top="455" left="81" width="359" height="12" font="4">record that a call frame has been entered and exited. The frame</text>
<text top="470" left="81" width="359" height="12" font="4">entry and exit LIR saves just enough information to allow the</text>
<text top="485" left="81" width="359" height="12" font="4">intepreter call stack to be restored later and is much simpler than</text>
<text top="500" left="81" width="359" height="12" font="4">the interpreter’s standard call code. If the function being entered</text>
<text top="515" left="81" width="359" height="12" font="4">is not constant (which in JavaScript includes any call by function</text>
<text top="530" left="81" width="359" height="12" font="4">name), the recorder must also emit LIR to guard that the function</text>
<text top="545" left="81" width="63" height="12" font="4">is the same.</text>
<text top="560" left="99" width="137" height="12" font="15">Guards and side exits.</text>
<text top="560" left="242" width="198" height="12" font="4">Each optimization described above</text>
<text top="575" left="81" width="359" height="12" font="4">requires one or more guards to verify the assumptions made in</text>
<text top="590" left="81" width="359" height="12" font="4">doing the optimization. A guard is just a group of LIR instructions</text>
<text top="605" left="81" width="359" height="12" font="4">that performs a test and conditional exit. The exit branches to a</text>
<text top="620" left="81" width="46" height="12" font="11">side exit</text>
<text top="619" left="127" width="313" height="12" font="4">, a small off-trace piece of LIR that returns a pointer to</text>
<text top="634" left="81" width="359" height="12" font="4">a structure that describes the reason for the exit along with the</text>
<text top="649" left="81" width="359" height="12" font="4">interpreter PC at the exit point and any other data needed to restore</text>
<text top="664" left="81" width="172" height="12" font="4">the interpreter’s state structures.</text>
<text top="679" left="99" width="43" height="12" font="15">Aborts.</text>
<text top="679" left="147" width="293" height="12" font="4">Some constructs are difficult to record in LIR traces.</text>
<text top="694" left="81" width="72" height="12" font="4">For example,</text>
<text top="695" left="158" width="28" height="11" font="7">eval</text>
<text top="694" left="192" width="248" height="12" font="4">or calls to external functions can change the</text>
<text top="709" left="81" width="359" height="12" font="4">program state in unpredictable ways, making it difficult for the</text>
<text top="724" left="81" width="359" height="12" font="4">tracer to know the current type map in order to continue tracing.</text>
<text top="739" left="81" width="359" height="12" font="4">A tracing implementation can also have any number of other limi-</text>
<text top="754" left="81" width="359" height="12" font="4">tations, e.g.,a small-memory device may limit the length of traces.</text>
<text top="769" left="81" width="359" height="12" font="4">When any situation occurs that prevents the implementation from</text>
<text top="784" left="81" width="251" height="12" font="4">continuing trace recording, the implementation</text>
<text top="784" left="335" width="34" height="12" font="11">aborts</text>
<text top="784" left="372" width="68" height="12" font="4">trace record-</text>
<text top="799" left="81" width="192" height="12" font="4">ing and returns to the trace monitor.</text>
<text top="835" left="81" width="17" height="12" font="15">3.2</text>
<text top="835" left="111" width="67" height="12" font="15">Trace Trees</text>
<text top="856" left="81" width="359" height="12" font="4">Especially simple loops, namely those where control flow, value</text>
<text top="871" left="81" width="359" height="12" font="4">types, value representations, and inlined functions are all invariant,</text>
<text top="886" left="81" width="359" height="12" font="4">can be represented by a single trace. But most loops have at least</text>
<text top="901" left="81" width="359" height="12" font="4">some variation, and so the program will take side exits from the</text>
<text top="916" left="81" width="359" height="12" font="4">main trace. When a side exit becomes hot, TraceMonkey starts a</text>
<text top="931" left="81" width="22" height="12" font="4">new</text>
<text top="931" left="107" width="69" height="12" font="11">branch trace</text>
<text top="931" left="179" width="261" height="12" font="4">from that point and patches the side exit to jump</text>
<text top="946" left="81" width="359" height="12" font="4">directly to that trace. In this way, a single trace expands on demand</text>
<text top="961" left="81" width="163" height="12" font="4">to a single-entry, multiple-exit</text>
<text top="961" left="247" width="51" height="12" font="11">trace tree</text>
<text top="961" left="298" width="3" height="12" font="4">.</text>
<text top="976" left="99" width="341" height="12" font="4">This section explains how trace trees are formed during execu-</text>
<text top="991" left="81" width="359" height="12" font="4">tion. The goal is to form trace trees during execution that cover all</text>
<text top="1006" left="81" width="155" height="12" font="4">the hot paths of the program.</text>
<text top="1048" left="81" width="4" height="8" font="20">1</text>
<text top="1050" left="88" width="352" height="11" font="21">Arrays are actually worse than this: if the index value is a number, it must</text>
<text top="1064" left="81" width="359" height="11" font="21">be converted from a double to a string for the property access operator, and</text>
<text top="1077" left="81" width="270" height="11" font="21">then to an integer internally to the array implementation.</text>
<text top="111" left="493" width="86" height="12" font="15">Starting a tree.</text>
<text top="111" left="582" width="252" height="12" font="4">Tree trees always start at loop headers, because</text>
<text top="126" left="476" width="359" height="12" font="4">they are a natural place to look for hot paths. In TraceMonkey, loop</text>
<text top="141" left="476" width="359" height="12" font="4">headers are easy to detect–the bytecode compiler ensures that a</text>
<text top="156" left="476" width="359" height="12" font="4">bytecode is a loop header iff it is the target of a backward branch.</text>
<text top="171" left="476" width="359" height="12" font="4">TraceMonkey starts a tree when a given loop header has been exe-</text>
<text top="186" left="476" width="359" height="12" font="4">cuted a certain number of times (2 in the current implementation).</text>
<text top="201" left="476" width="359" height="12" font="4">Starting a tree just means starting recording a trace for the current</text>
<text top="215" left="476" width="359" height="12" font="4">point and type map and marking the trace as the root of a tree. Each</text>
<text top="230" left="476" width="359" height="12" font="4">tree is associated with a loop header and type map, so there may be</text>
<text top="245" left="476" width="196" height="12" font="4">several trees for a given loop header.</text>
<text top="260" left="493" width="96" height="12" font="15">Closing the loop.</text>
<text top="260" left="593" width="219" height="12" font="4">Trace recording can end in several ways.</text>
<text top="275" left="493" width="341" height="12" font="4">Ideally, the trace reaches the loop header where it started with</text>
<text top="290" left="476" width="266" height="12" font="4">the same type map as on entry. This is called a</text>
<text top="290" left="746" width="59" height="12" font="11">type-stable</text>
<text top="290" left="810" width="24" height="12" font="4">loop</text>
<text top="305" left="476" width="359" height="12" font="4">iteration. In this case, the end of the trace can jump right to the</text>
<text top="320" left="476" width="359" height="12" font="4">beginning, as all the value representations are exactly as needed to</text>
<text top="335" left="476" width="359" height="12" font="4">enter the trace. The jump can even skip the usual code that would</text>
<text top="350" left="476" width="359" height="12" font="4">copy out the state at the end of the trace and copy it back in to the</text>
<text top="365" left="476" width="206" height="12" font="4">trace activation record to enter a trace.</text>
<text top="380" left="493" width="341" height="12" font="4">In certain cases the trace might reach the loop header with a</text>
<text top="395" left="476" width="359" height="12" font="4">different type map. This scenario is sometime observed for the first</text>
<text top="410" left="476" width="359" height="12" font="4">iteration of a loop. Some variables inside the loop might initially be</text>
<text top="425" left="476" width="52" height="12" font="11">undefined</text>
<text top="425" left="528" width="306" height="12" font="4">, before they are set to a concrete type during the first loop</text>
<text top="440" left="476" width="359" height="12" font="4">iteration. When recording such an iteration, the recorder cannot</text>
<text top="455" left="476" width="279" height="12" font="4">link the trace back to its own loop header since it is</text>
<text top="455" left="758" width="72" height="12" font="11">type-unstable</text>
<text top="455" left="831" width="3" height="12" font="4">.</text>
<text top="469" left="476" width="359" height="12" font="4">Instead, the iteration is terminated with a side exit that will always</text>
<text top="484" left="476" width="359" height="12" font="4">fail and return to the interpreter. At the same time a new trace is</text>
<text top="499" left="476" width="359" height="12" font="4">recorded with the new type map. Every time an additional type-</text>
<text top="514" left="476" width="359" height="12" font="4">unstable trace is added to a region, its exit type map is compared to</text>
<text top="529" left="476" width="359" height="12" font="4">the entry map of all existing traces in case they complement each</text>
<text top="544" left="476" width="359" height="12" font="4">other. With this approach we are able to cover type-unstable loop</text>
<text top="559" left="476" width="320" height="12" font="4">iterations as long they eventually form a stable equilibrium.</text>
<text top="574" left="493" width="341" height="12" font="4">Finally, the trace might exit the loop before reaching the loop</text>
<text top="589" left="476" width="260" height="12" font="4">header, for example because execution reaches a</text>
<text top="590" left="739" width="35" height="11" font="7">break</text>
<text top="589" left="777" width="11" height="12" font="4">or</text>
<text top="590" left="792" width="42" height="11" font="7">return</text>
<text top="604" left="476" width="359" height="12" font="4">statement. In this case, the VM simply ends the trace with an exit</text>
<text top="619" left="476" width="108" height="12" font="4">to the trace monitor.</text>
<text top="634" left="493" width="341" height="12" font="4">As mentioned previously, we may speculatively chose to rep-</text>
<text top="649" left="476" width="359" height="12" font="4">resent certain Number-typed values as integers on trace. We do so</text>
<text top="664" left="476" width="359" height="12" font="4">when we observe that Number-typed variables contain an integer</text>
<text top="679" left="476" width="359" height="12" font="4">value at trace entry. If during trace recording the variable is unex-</text>
<text top="694" left="476" width="359" height="12" font="4">pectedly assigned a non-integer value, we have to widen the type</text>
<text top="709" left="476" width="359" height="12" font="4">of the variable to a double. As a result, the recorded trace becomes</text>
<text top="724" left="476" width="359" height="12" font="4">inherently type-unstable since it starts with an integer value but</text>
<text top="738" left="476" width="359" height="12" font="4">ends with a double value. This represents a mis-speculation, since</text>
<text top="753" left="476" width="359" height="12" font="4">at trace entry we specialized the Number-typed value to an integer,</text>
<text top="768" left="476" width="359" height="12" font="4">assuming that at the loop edge we would again find an integer value</text>
<text top="783" left="476" width="359" height="12" font="4">in the variable, allowing us to close the loop. To avoid future spec-</text>
<text top="798" left="476" width="359" height="12" font="4">ulative failures involving this variable, and to obtain a type-stable</text>
<text top="813" left="476" width="359" height="12" font="4">trace we note the fact that the variable in question as been observed</text>
<text top="828" left="476" width="359" height="12" font="4">to sometimes hold non-integer values in an advisory data structure</text>
<text top="843" left="476" width="146" height="12" font="4">which we call the “oracle”.</text>
<text top="858" left="493" width="341" height="12" font="4">When compiling loops, we consult the oracle before specializ-</text>
<text top="873" left="476" width="359" height="12" font="4">ing values to integers. Speculation towards integers is performed</text>
<text top="888" left="476" width="359" height="12" font="4">only if no adverse information is known to the oracle about that</text>
<text top="903" left="476" width="359" height="12" font="4">particular variable. Whenever we accidentally compile a loop that</text>
<text top="918" left="476" width="359" height="12" font="4">is type-unstable due to mis-speculation of a Number-typed vari-</text>
<text top="933" left="476" width="359" height="12" font="4">able, we immediately trigger the recording of a new trace, which</text>
<text top="948" left="476" width="359" height="12" font="4">based on the now updated oracle information will start with a dou-</text>
<text top="963" left="476" width="207" height="12" font="4">ble value and thus become type stable.</text>
<text top="977" left="493" width="103" height="12" font="15">Extending a tree.</text>
<text top="978" left="602" width="232" height="12" font="4">Side exits lead to different paths through</text>
<text top="993" left="476" width="359" height="12" font="4">the loop, or paths with different types or representations. Thus, to</text>
<text top="1007" left="476" width="359" height="12" font="4">completely cover the loop, the VM must record traces starting at all</text>
<text top="1022" left="476" width="359" height="12" font="4">side exits. These traces are recorded much like root traces: there is</text>
<text top="1037" left="476" width="359" height="12" font="4">a counter for each side exit, and when the counter reaches a hotness</text>
<text top="1052" left="476" width="359" height="12" font="4">threshold, recording starts. Recording stops exactly as for the root</text>
<text top="1067" left="476" width="355" height="12" font="4">trace, using the loop header of the root trace as the target to reach.</text>
</page>
<page number="6" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="22" size="13" family="NVCFEO+Calibri" color="#000000"/>
	<fontspec id="23" size="7" family="NVCFEO+Calibri" color="#000000"/>
	<fontspec id="24" size="7" family="ZBVPYI+Calibri" color="#000000"/>
	<fontspec id="25" size="6" family="ZBVPYI+Calibri" color="#000000"/>
	<fontspec id="26" size="10" family="ZBVPYI+Calibri" color="#000000"/>
<text top="111" left="99" width="341" height="12" font="4">Our implementation does not extend at all side exits. It extends</text>
<text top="126" left="81" width="359" height="12" font="4">only if the side exit is for a control-flow branch, and only if the side</text>
<text top="141" left="81" width="359" height="12" font="4">exit does not leave the loop. In particular we do not want to extend</text>
<text top="156" left="81" width="359" height="12" font="4">a trace tree along a path that leads to an outer loop, because we</text>
<text top="171" left="81" width="286" height="12" font="4">want to cover such paths in an outer tree through tree</text>
<text top="171" left="370" width="39" height="12" font="11">nesting</text>
<text top="171" left="409" width="3" height="12" font="4">.</text>
<text top="197" left="81" width="17" height="12" font="15">3.3</text>
<text top="197" left="111" width="68" height="12" font="15">Blacklisting</text>
<text top="218" left="81" width="359" height="12" font="4">Sometimes, a program follows a path that cannot be compiled</text>
<text top="233" left="81" width="359" height="12" font="4">into a trace, usually because of limitations in the implementation.</text>
<text top="248" left="81" width="359" height="12" font="4">TraceMonkey does not currently support recording throwing and</text>
<text top="263" left="81" width="359" height="12" font="4">catching of arbitrary exceptions. This design trade off was chosen,</text>
<text top="278" left="81" width="359" height="12" font="4">because exceptions are usually rare in JavaScript. However, if a</text>
<text top="293" left="81" width="359" height="12" font="4">program opts to use exceptions intensively, we would suddenly</text>
<text top="307" left="81" width="359" height="12" font="4">incur a punishing runtime overhead if we repeatedly try to record</text>
<text top="322" left="81" width="359" height="12" font="4">a trace for this path and repeatedly fail to do so, since we abort</text>
<text top="337" left="81" width="311" height="12" font="4">tracing every time we observe an exception being thrown.</text>
<text top="352" left="99" width="341" height="12" font="4">As a result, if a hot loop contains traces that always fail, the VM</text>
<text top="367" left="81" width="359" height="12" font="4">could potentially run much more slowly than the base interpreter:</text>
<text top="382" left="81" width="359" height="12" font="4">the VM repeatedly spends time trying to record traces, but is never</text>
<text top="397" left="81" width="359" height="12" font="4">able to run any. To avoid this problem, whenever the VM is about</text>
<text top="412" left="81" width="359" height="12" font="4">to start tracing, it must try to predict whether it will finish the trace.</text>
<text top="427" left="99" width="209" height="12" font="4">Our prediction algorithm is based on</text>
<text top="427" left="314" width="63" height="12" font="11">blacklisting</text>
<text top="427" left="382" width="57" height="12" font="4">traces that</text>
<text top="442" left="81" width="359" height="12" font="4">have been tried and failed. When the VM fails to finish a trace start-</text>
<text top="457" left="81" width="359" height="12" font="4">ing at a given point, the VM records that a failure has occurred. The</text>
<text top="472" left="81" width="359" height="12" font="4">VM also sets a counter so that it will not try to record a trace starting</text>
<text top="487" left="81" width="359" height="12" font="4">at that point until it is passed a few more times (32 in our imple-</text>
<text top="502" left="81" width="90" height="12" font="4">mentation). This</text>
<text top="502" left="176" width="39" height="12" font="11">backoff</text>
<text top="502" left="221" width="218" height="12" font="4">counter gives temporary conditions that</text>
<text top="517" left="81" width="359" height="12" font="4">prevent tracing a chance to end. For example, a loop may behave</text>
<text top="532" left="81" width="359" height="12" font="4">differently during startup than during its steady-state execution. Af-</text>
<text top="547" left="81" width="359" height="12" font="4">ter a given number of failures (2 in our implementation), the VM</text>
<text top="562" left="81" width="359" height="12" font="4">marks the fragment as blacklisted, which means the VM will never</text>
<text top="576" left="81" width="181" height="12" font="4">again start recording at that point.</text>
<text top="591" left="99" width="341" height="12" font="4">After implementing this basic strategy, we observed that for</text>
<text top="606" left="81" width="359" height="12" font="4">small loops that get blacklisted, the system can spend a noticeable</text>
<text top="621" left="81" width="359" height="12" font="4">amount of time just finding the loop fragment and determining that</text>
<text top="636" left="81" width="359" height="12" font="4">it has been blacklisted. We now avoid that problem by patching the</text>
<text top="651" left="81" width="359" height="12" font="4">bytecode. We define an extra no-op bytecode that indicates a loop</text>
<text top="666" left="81" width="359" height="12" font="4">header. The VM calls into the trace monitor every time the inter-</text>
<text top="681" left="81" width="359" height="12" font="4">preter executes a loop header no-op. To blacklist a fragment, we</text>
<text top="696" left="81" width="359" height="12" font="4">simply replace the loop header no-op with a regular no-op. Thus,</text>
<text top="711" left="81" width="338" height="12" font="4">the interpreter will never again even call into the trace monitor.</text>
<text top="726" left="99" width="341" height="12" font="4">There is a related problem we have not yet solved, which occurs</text>
<text top="741" left="81" width="226" height="12" font="4">when a loop meets all of these conditions:</text>
<text top="762" left="89" width="6" height="11" font="2">•</text>
<text top="763" left="100" width="285" height="12" font="4">The VM can form at least one root trace for the loop.</text>
<text top="783" left="89" width="6" height="11" font="2">•</text>
<text top="784" left="100" width="339" height="12" font="4">There is at least one hot side exit for which the VM cannot</text>
<text top="799" left="100" width="91" height="12" font="4">complete a trace.</text>
<text top="819" left="89" width="6" height="11" font="2">•</text>
<text top="820" left="100" width="124" height="12" font="4">The loop body is short.</text>
<text top="842" left="99" width="341" height="12" font="4">In this case, the VM will repeatedly pass the loop header, search</text>
<text top="857" left="81" width="359" height="12" font="4">for a trace, find it, execute it, and fall back to the interpreter.</text>
<text top="872" left="81" width="359" height="12" font="4">With a short loop body, the overhead of finding and calling the</text>
<text top="887" left="81" width="359" height="12" font="4">trace is high, and causes performance to be even slower than the</text>
<text top="902" left="81" width="359" height="12" font="4">basic interpreter. So far, in this situation we have improved the</text>
<text top="917" left="81" width="359" height="12" font="4">implementation so that the VM can complete the branch trace.</text>
<text top="932" left="81" width="359" height="12" font="4">But it is hard to guarantee that this situation will never happen.</text>
<text top="947" left="81" width="359" height="12" font="4">As future work, this situation could be avoided by detecting and</text>
<text top="962" left="81" width="359" height="12" font="4">blacklisting loops for which the average trace call executes few</text>
<text top="977" left="81" width="240" height="12" font="4">bytecodes before returning to the interpreter.</text>
<text top="1008" left="81" width="12" height="15" font="9">4.</text>
<text top="1008" left="110" width="205" height="15" font="9">Nested Trace Tree Formation</text>
<text top="1031" left="81" width="359" height="12" font="4">Figure 7 shows basic trace tree compilation (11) applied to a nested</text>
<text top="1046" left="81" width="359" height="12" font="4">loop where the inner loop contains two paths. Usually, the inner</text>
<text top="1061" left="81" width="108" height="12" font="4">loop (with header at</text>
<text top="1061" left="192" width="5" height="12" font="18">i</text>
<text top="1066" left="196" width="5" height="8" font="8">2</text>
<text top="1061" left="203" width="237" height="12" font="4">) becomes hot first, and a trace tree is rooted</text>
<text top="1076" left="81" width="359" height="12" font="4">at that point. For example, the first recorded trace may be a cycle</text>
<text top="122" left="612" width="7" height="16" font="22"><b>T</b></text>
<text top="156" left="674" width="32" height="8" font="23"><b>Trunk Trace</b></text>
<text top="141" left="674" width="34" height="8" font="23"><b>Tree Anchor</b></text>
<text top="171" left="672" width="36" height="8" font="23"><b>Trace Anchor</b></text>
<text top="186" left="673" width="35" height="8" font="23"><b>Branch Trace</b></text>
<text top="201" left="682" width="17" height="8" font="23"><b>Guard</b></text>
<text top="216" left="678" width="24" height="8" font="23"><b>Side Exit</b></text>
<text top="335" left="476" width="53" height="12" font="15">Figure 5.</text>
<text top="335" left="536" width="299" height="12" font="4">A tree with two traces, a trunk trace and one branch</text>
<text top="350" left="476" width="359" height="12" font="4">trace. The trunk trace contains a guard to which a branch trace was</text>
<text top="365" left="476" width="359" height="12" font="4">attached. The branch trace contain a guard that may fail and trigger</text>
<text top="380" left="476" width="359" height="12" font="4">a side exit. Both the trunk and the branch trace loop back to the tree</text>
<text top="395" left="476" width="255" height="12" font="4">anchor, which is the beginning of the trace tree.</text>
<text top="442" left="601" width="20" height="9" font="24"><b>Trace 2</b></text>
<text top="442" left="551" width="20" height="9" font="24"><b>Trace 1</b></text>
<text top="442" left="735" width="20" height="9" font="24"><b>Trace 2</b></text>
<text top="442" left="685" width="20" height="9" font="24"><b>Trace 1</b></text>
<text top="542" left="551" width="19" height="9" font="24"><b>Closed</b></text>
<text top="542" left="602" width="19" height="9" font="24"><b>Linked</b></text>
<text top="542" left="686" width="19" height="9" font="24"><b>Linked</b></text>
<text top="542" left="736" width="19" height="9" font="24"><b>Linked</b></text>
<text top="603" left="538" width="19" height="7" font="25"><b>Number</b></text>
<text top="660" left="596" width="19" height="7" font="25"><b>Number</b></text>
<text top="605" left="729" width="14" height="7" font="25"><b>String</b></text>
<text top="660" left="663" width="14" height="7" font="25"><b>String</b></text>
<text top="659" left="729" width="14" height="7" font="25"><b>String</b></text>
<text top="670" left="543" width="14" height="7" font="25"><b>String</b></text>
<text top="604" left="663" width="19" height="7" font="25"><b>Boolean</b></text>
<text top="578" left="647" width="20" height="9" font="24"><b>Trace 2</b></text>
<text top="578" left="551" width="20" height="9" font="24"><b>Trace 1</b></text>
<text top="578" left="736" width="20" height="9" font="24"><b>Trace 3</b></text>
<text top="689" left="551" width="19" height="9" font="24"><b>Linked</b></text>
<text top="683" left="610" width="19" height="9" font="24"><b>Linked</b></text>
<text top="683" left="647" width="19" height="9" font="24"><b>Linked</b></text>
<text top="683" left="736" width="19" height="9" font="24"><b>Closed</b></text>
<text top="467" left="538" width="19" height="7" font="25"><b>Number</b></text>
<text top="525" left="538" width="19" height="7" font="25"><b>Number</b></text>
<text top="525" left="615" width="19" height="7" font="25"><b>Number</b></text>
<text top="467" left="615" width="19" height="7" font="25"><b>Boolean</b></text>
<text top="467" left="672" width="19" height="7" font="25"><b>Number</b></text>
<text top="525" left="672" width="19" height="7" font="25"><b>Boolean</b></text>
<text top="525" left="749" width="19" height="7" font="25"><b>Number</b></text>
<text top="467" left="749" width="19" height="7" font="25"><b>Boolean</b></text>
<text top="551" left="581" width="11" height="12" font="26"><b>(a)</b></text>
<text top="550" left="714" width="11" height="12" font="26"><b>(b)</b></text>
<text top="696" left="654" width="10" height="12" font="26"><b>(c)</b></text>
<text top="738" left="476" width="54" height="12" font="15">Figure 6.</text>
<text top="738" left="536" width="298" height="12" font="4">We handle type-unstable loops by allowing traces to</text>
<text top="753" left="476" width="359" height="12" font="4">compile that cannot loop back to themselves due to a type mis-</text>
<text top="768" left="476" width="359" height="12" font="4">match. As such traces accumulate, we attempt to connect their loop</text>
<text top="783" left="476" width="359" height="12" font="4">edges to form groups of trace trees that can execute without having</text>
<text top="798" left="476" width="359" height="12" font="4">to side-exit to the interpreter to cover odd type cases. This is par-</text>
<text top="813" left="476" width="359" height="12" font="4">ticularly important for nested trace trees where an outer tree tries to</text>
<text top="828" left="476" width="359" height="12" font="4">call an inner tree (or in this case a forest of inner trees), since inner</text>
<text top="843" left="476" width="359" height="12" font="4">loops frequently have initially undefined values which change type</text>
<text top="858" left="476" width="225" height="12" font="4">to a concrete value after the first iteration.</text>
<text top="897" left="476" width="130" height="12" font="4">through the inner loop,</text>
<text top="896" left="611" width="7" height="13" font="6">{</text>
<text top="897" left="617" width="5" height="12" font="18">i</text>
<text top="901" left="622" width="5" height="8" font="8">2</text>
<text top="897" left="628" width="11" height="12" font="18">, i</text>
<text top="901" left="639" width="5" height="8" font="8">3</text>
<text top="897" left="646" width="11" height="12" font="18">, i</text>
<text top="901" left="656" width="5" height="8" font="8">5</text>
<text top="897" left="663" width="15" height="12" font="18">, α</text>
<text top="896" left="678" width="7" height="13" font="6">}</text>
<text top="897" left="685" width="30" height="12" font="4">. The</text>
<text top="897" left="720" width="9" height="12" font="18">α</text>
<text top="897" left="734" width="100" height="12" font="4">symbol is used to</text>
<text top="912" left="476" width="263" height="12" font="4">indicate that the trace loops back the tree anchor.</text>
<text top="927" left="493" width="341" height="12" font="4">When execution leaves the inner loop, the basic design has two</text>
<text top="942" left="476" width="359" height="12" font="4">choices. First, the system can stop tracing and give up on compiling</text>
<text top="957" left="476" width="359" height="12" font="4">the outer loop, clearly an undesirable solution. The other choice is</text>
<text top="972" left="476" width="359" height="12" font="4">to continue tracing, compiling traces for the outer loop inside the</text>
<text top="987" left="476" width="120" height="12" font="4">inner loop’s trace tree.</text>
<text top="1001" left="493" width="214" height="12" font="4">For example, the program might exit at</text>
<text top="1001" left="711" width="5" height="12" font="18">i</text>
<text top="1006" left="716" width="5" height="8" font="8">5</text>
<text top="1001" left="726" width="108" height="12" font="4">and record a branch</text>
<text top="1016" left="476" width="222" height="12" font="4">trace that incorporates the outer loop:</text>
<text top="1015" left="706" width="7" height="13" font="6">{</text>
<text top="1016" left="712" width="5" height="12" font="18">i</text>
<text top="1021" left="717" width="5" height="8" font="8">5</text>
<text top="1016" left="723" width="11" height="12" font="18">, i</text>
<text top="1021" left="734" width="5" height="8" font="8">7</text>
<text top="1016" left="740" width="11" height="12" font="18">, i</text>
<text top="1021" left="751" width="5" height="8" font="8">1</text>
<text top="1016" left="758" width="11" height="12" font="18">, i</text>
<text top="1021" left="768" width="5" height="8" font="8">6</text>
<text top="1016" left="775" width="11" height="12" font="18">, i</text>
<text top="1021" left="786" width="5" height="8" font="8">7</text>
<text top="1016" left="792" width="11" height="12" font="18">, i</text>
<text top="1021" left="803" width="5" height="8" font="8">1</text>
<text top="1016" left="809" width="15" height="12" font="18">, α</text>
<text top="1015" left="824" width="7" height="13" font="6">}</text>
<text top="1016" left="831" width="3" height="12" font="4">.</text>
<text top="1031" left="476" width="287" height="12" font="4">Later, the program might take the other branch at</text>
<text top="1031" left="768" width="5" height="12" font="18">i</text>
<text top="1036" left="773" width="5" height="8" font="8">2</text>
<text top="1031" left="785" width="49" height="12" font="4">and then</text>
<text top="1046" left="476" width="359" height="12" font="4">exit, recording another branch trace incorporating the outer loop:</text>
<text top="1060" left="476" width="7" height="13" font="6">{</text>
<text top="1061" left="482" width="5" height="12" font="18">i</text>
<text top="1066" left="487" width="5" height="8" font="8">2</text>
<text top="1061" left="493" width="11" height="12" font="18">, i</text>
<text top="1066" left="504" width="5" height="8" font="8">4</text>
<text top="1061" left="510" width="11" height="12" font="18">, i</text>
<text top="1066" left="521" width="5" height="8" font="8">5</text>
<text top="1061" left="528" width="11" height="12" font="18">, i</text>
<text top="1066" left="538" width="5" height="8" font="8">7</text>
<text top="1061" left="545" width="11" height="12" font="18">, i</text>
<text top="1066" left="556" width="5" height="8" font="8">1</text>
<text top="1061" left="562" width="11" height="12" font="18">, i</text>
<text top="1066" left="573" width="5" height="8" font="8">6</text>
<text top="1061" left="579" width="11" height="12" font="18">, i</text>
<text top="1066" left="590" width="5" height="8" font="8">7</text>
<text top="1061" left="596" width="11" height="12" font="18">, i</text>
<text top="1066" left="607" width="5" height="8" font="8">1</text>
<text top="1061" left="613" width="15" height="12" font="18">, α</text>
<text top="1060" left="628" width="7" height="13" font="6">}</text>
<text top="1061" left="635" width="199" height="12" font="4">. Thus, the outer loop is recorded and</text>
<text top="1076" left="476" width="359" height="12" font="4">compiled twice, and both copies must be retained in the trace cache.</text>
</page>
<page number="7" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="27" size="7" family="XMYAFE+Calibri" color="#000000"/>
	<fontspec id="28" size="5" family="XMYAFE+Calibri" color="#000000"/>
	<fontspec id="29" size="6" family="XMYAFE+Calibri" color="#000000"/>
	<fontspec id="30" size="9" family="XMYAFE+Calibri" color="#000000"/>
	<fontspec id="31" size="13" family="RYTUZQ+CMR9" color="#000000"/>
	<fontspec id="32" size="7" family="BLSTWU+Calibri" color="#000000"/>
	<fontspec id="33" size="5" family="BLSTWU+Calibri" color="#000000"/>
	<fontspec id="34" size="6" family="BLSTWU+Calibri" color="#000000"/>
	<fontspec id="35" size="11" family="KUYGUP+NimbusRomNo9L-Regu" color="#000000"/>
<text top="153" left="200" width="2" height="9" font="27"><b>i</b></text>
<text top="155" left="202" width="3" height="6" font="28"><b>2</b></text>
<text top="192" left="181" width="2" height="9" font="27"><b>i</b></text>
<text top="194" left="183" width="3" height="6" font="28"><b>3</b></text>
<text top="192" left="219" width="2" height="9" font="27"><b>i</b></text>
<text top="194" left="221" width="3" height="6" font="28"><b>4</b></text>
<text top="225" left="201" width="2" height="9" font="27"><b>i</b></text>
<text top="227" left="203" width="3" height="6" font="28"><b>5</b></text>
<text top="120" left="200" width="2" height="9" font="27"><b>i</b></text>
<text top="122" left="202" width="3" height="6" font="28"><b>1</b></text>
<text top="191" left="154" width="2" height="9" font="27"><b>i</b></text>
<text top="193" left="156" width="3" height="6" font="28"><b>6</b></text>
<text top="258" left="200" width="2" height="9" font="27"><b>i</b></text>
<text top="260" left="202" width="3" height="6" font="28"><b>7</b></text>
<text top="122" left="267" width="3" height="9" font="27"><b>t</b></text>
<text top="124" left="270" width="3" height="6" font="28"><b>1</b></text>
<text top="188" left="314" width="3" height="9" font="27"><b>t</b></text>
<text top="190" left="317" width="3" height="6" font="28"><b>2</b></text>
<text top="137" left="334" width="22" height="8" font="29"><b>Tree Call</b></text>
<text top="118" left="317" width="28" height="8" font="29"><b>Outer Tree</b></text>
<text top="165" left="334" width="31" height="8" font="29"><b>Nested Tree</b></text>
<text top="255" left="336" width="27" height="8" font="29"><b>Exit Guard</b></text>
<text top="299" left="198" width="11" height="12" font="30"><b>(a)</b></text>
<text top="297" left="305" width="11" height="12" font="30"><b>(b)</b></text>
<text top="339" left="81" width="51" height="12" font="15">Figure 7.</text>
<text top="339" left="139" width="301" height="12" font="4">Control flow graph of a nested loop with an if statement</text>
<text top="354" left="81" width="359" height="12" font="4">inside the inner most loop (a). An inner tree captures the inner</text>
<text top="369" left="81" width="359" height="12" font="4">loop, and is nested inside an outer tree which “calls” the inner tree.</text>
<text top="384" left="81" width="359" height="12" font="4">The inner tree returns to the outer tree once it exits along its loop</text>
<text top="399" left="81" width="107" height="12" font="4">condition guard (b).</text>
<text top="442" left="81" width="204" height="12" font="4">In general, if loops are nested to depth</text>
<text top="442" left="288" width="7" height="12" font="18">k</text>
<text top="442" left="295" width="101" height="12" font="4">, and each loop has</text>
<text top="442" left="400" width="8" height="12" font="18">n</text>
<text top="442" left="411" width="28" height="12" font="4">paths</text>
<text top="457" left="81" width="276" height="12" font="4">(on geometric average), this na¨ıve strategy yields</text>
<text top="457" left="363" width="11" height="12" font="18">O</text>
<text top="457" left="374" width="5" height="12" font="31">(</text>
<text top="457" left="379" width="8" height="12" font="18">n</text>
<text top="455" left="387" width="6" height="8" font="19">k</text>
<text top="457" left="394" width="5" height="12" font="31">)</text>
<text top="457" left="405" width="35" height="12" font="4">traces,</text>
<text top="472" left="81" width="195" height="12" font="4">which can easily fill the trace cache.</text>
<text top="487" left="99" width="341" height="12" font="4">In order to execute programs with nested loops efficiently, a</text>
<text top="502" left="81" width="359" height="12" font="4">tracing system needs a technique for covering the nested loops with</text>
<text top="517" left="81" width="268" height="12" font="4">native code without exponential trace duplication.</text>
<text top="545" left="81" width="17" height="12" font="15">4.1</text>
<text top="545" left="111" width="106" height="12" font="15">Nesting Algorithm</text>
<text top="566" left="81" width="359" height="12" font="4">The key insight is that if each loop is represented by its own trace</text>
<text top="581" left="81" width="359" height="12" font="4">tree, the code for each loop can be contained only in its own tree,</text>
<text top="595" left="81" width="359" height="12" font="4">and outer loop paths will not be duplicated. Another key fact is that</text>
<text top="610" left="81" width="359" height="12" font="4">we are not tracing arbitrary bytecodes that might have irreduceable</text>
<text top="625" left="81" width="359" height="12" font="4">control flow graphs, but rather bytecodes produced by a compiler</text>
<text top="640" left="81" width="359" height="12" font="4">for a language with structured control flow. Thus, given two loop</text>
<text top="655" left="81" width="359" height="12" font="4">edges, the system can easily determine whether they are nested</text>
<text top="670" left="81" width="359" height="12" font="4">and which is the inner loop. Using this knowledge, the system can</text>
<text top="685" left="81" width="359" height="12" font="4">compile inner and outer loops separately, and make the outer loop’s</text>
<text top="700" left="81" width="31" height="12" font="4">traces</text>
<text top="700" left="116" width="20" height="12" font="11">call</text>
<text top="700" left="139" width="140" height="12" font="4">the inner loop’s trace tree.</text>
<text top="715" left="99" width="341" height="12" font="4">The algorithm for building nested trace trees is as follows. We</text>
<text top="730" left="81" width="359" height="12" font="4">start tracing at loop headers exactly as in the basic tracing system.</text>
<text top="745" left="81" width="359" height="12" font="4">When we exit a loop (detected by comparing the interpreter PC</text>
<text top="760" left="81" width="359" height="12" font="4">with the range given by the loop edge), we stop the trace. The</text>
<text top="775" left="81" width="359" height="12" font="4">key step of the algorithm occurs when we are recording a trace</text>
<text top="790" left="81" width="44" height="12" font="4">for loop</text>
<text top="790" left="129" width="9" height="12" font="18">L</text>
<text top="794" left="138" width="8" height="8" font="19">R</text>
<text top="790" left="151" width="4" height="12" font="4">(</text>
<text top="790" left="156" width="10" height="12" font="18">R</text>
<text top="790" left="170" width="270" height="12" font="4">for loop being recorded) and we reach the header</text>
<text top="805" left="81" width="97" height="12" font="4">of a different loop</text>
<text top="804" left="181" width="9" height="12" font="18">L</text>
<text top="809" left="191" width="8" height="8" font="19">O</text>
<text top="805" left="203" width="4" height="12" font="4">(</text>
<text top="804" left="208" width="11" height="12" font="18">O</text>
<text top="805" left="222" width="134" height="12" font="4">for other loop). Note that</text>
<text top="804" left="360" width="9" height="12" font="18">L</text>
<text top="809" left="369" width="8" height="8" font="19">O</text>
<text top="805" left="382" width="58" height="12" font="4">must be an</text>
<text top="820" left="81" width="69" height="12" font="4">inner loop of</text>
<text top="819" left="154" width="9" height="12" font="18">L</text>
<text top="824" left="163" width="8" height="8" font="19">R</text>
<text top="820" left="176" width="252" height="12" font="4">because we stop the trace when we exit a loop.</text>
<text top="841" left="89" width="6" height="11" font="2">•</text>
<text top="842" left="100" width="9" height="12" font="4">If</text>
<text top="842" left="113" width="9" height="12" font="18">L</text>
<text top="847" left="123" width="8" height="8" font="19">O</text>
<text top="842" left="136" width="265" height="12" font="4">has a type-matching compiled trace tree, we call</text>
<text top="842" left="406" width="9" height="12" font="18">L</text>
<text top="847" left="415" width="8" height="8" font="19">O</text>
<text top="842" left="428" width="11" height="12" font="4">as</text>
<text top="857" left="100" width="339" height="12" font="4">a nested trace tree. If the call succeeds, then we record the call</text>
<text top="872" left="100" width="79" height="12" font="4">in the trace for</text>
<text top="872" left="183" width="9" height="12" font="18">L</text>
<text top="877" left="193" width="8" height="8" font="19">R</text>
<text top="872" left="202" width="192" height="12" font="4">. On future executions, the trace for</text>
<text top="872" left="397" width="9" height="12" font="18">L</text>
<text top="877" left="406" width="8" height="8" font="19">R</text>
<text top="872" left="419" width="21" height="12" font="4">will</text>
<text top="887" left="100" width="147" height="12" font="4">call the inner trace directly.</text>
<text top="907" left="89" width="6" height="11" font="2">•</text>
<text top="908" left="100" width="9" height="12" font="4">If</text>
<text top="908" left="114" width="9" height="12" font="18">L</text>
<text top="913" left="123" width="8" height="8" font="19">O</text>
<text top="908" left="137" width="302" height="12" font="4">does not have a type-matching compiled trace tree yet,</text>
<text top="923" left="100" width="339" height="12" font="4">we have to obtain it before we are able to proceed. In order</text>
<text top="938" left="100" width="339" height="12" font="4">to do this, we simply abort recording the first trace. The trace</text>
<text top="953" left="100" width="339" height="12" font="4">monitor will see the inner loop header, and will immediately</text>
<text top="968" left="100" width="159" height="12" font="4">start recording the inner loop.</text>
<text top="966" left="263" width="4" height="8" font="20">2</text>
<text top="991" left="99" width="341" height="12" font="4">If all the loops in a nest are type-stable, then loop nesting creates</text>
<text top="1006" left="81" width="295" height="12" font="4">no duplication. Otherwise, if loops are nested to a depth</text>
<text top="1006" left="379" width="7" height="12" font="18">k</text>
<text top="1006" left="387" width="53" height="12" font="4">, and each</text>
<text top="1035" left="81" width="4" height="8" font="20">2</text>
<text top="1037" left="88" width="352" height="11" font="21">Instead of aborting the outer recording, we could principally merely sus-</text>
<text top="1050" left="81" width="359" height="11" font="21">pend the recording, but that would require the implementation to be able</text>
<text top="1064" left="81" width="359" height="11" font="21">to record several traces simultaneously, complicating the implementation,</text>
<text top="1077" left="81" width="246" height="11" font="21">while saving only a few iterations in the interpreter.</text>
<text top="151" left="598" width="2" height="8" font="32"><b>i</b></text>
<text top="153" left="600" width="3" height="6" font="33"><b>2</b></text>
<text top="181" left="598" width="2" height="8" font="32"><b>i</b></text>
<text top="183" left="600" width="3" height="6" font="33"><b>3</b></text>
<text top="119" left="598" width="2" height="8" font="32"><b>i</b></text>
<text top="121" left="600" width="3" height="6" font="33"><b>1</b></text>
<text top="270" left="598" width="2" height="8" font="32"><b>i</b></text>
<text top="272" left="600" width="3" height="6" font="33"><b>6</b></text>
<text top="213" left="598" width="2" height="8" font="32"><b>i</b></text>
<text top="214" left="600" width="3" height="6" font="33"><b>4</b></text>
<text top="242" left="598" width="2" height="8" font="32"><b>i</b></text>
<text top="244" left="600" width="3" height="6" font="33"><b>5</b></text>
<text top="151" left="671" width="2" height="8" font="32"><b>t</b></text>
<text top="153" left="674" width="3" height="6" font="33"><b>2</b></text>
<text top="117" left="645" width="2" height="8" font="32"><b>t</b></text>
<text top="119" left="648" width="3" height="6" font="33"><b>1</b></text>
<text top="216" left="671" width="2" height="8" font="32"><b>t</b></text>
<text top="217" left="674" width="3" height="6" font="33"><b>4</b></text>
<text top="204" left="695" width="26" height="7" font="34"><b>Exit Guard</b></text>
<text top="129" left="689" width="29" height="7" font="34"><b>Nested Tree</b></text>
<text top="311" left="476" width="51" height="12" font="15">Figure 8.</text>
<text top="311" left="533" width="301" height="12" font="4">Control flow graph of a loop with two nested loops (left)</text>
<text top="326" left="476" width="359" height="12" font="4">and its nested trace tree configuration (right). The outer tree calls</text>
<text top="341" left="476" width="359" height="12" font="4">the two inner nested trace trees and places guards at their side exit</text>
<text top="356" left="476" width="52" height="12" font="4">locations.</text>
<text top="406" left="476" width="106" height="12" font="4">loop is entered with</text>
<text top="405" left="585" width="12" height="12" font="18">m</text>
<text top="406" left="600" width="234" height="12" font="4">different type maps (on geometric average),</text>
<text top="421" left="476" width="90" height="12" font="4">then we compile</text>
<text top="421" left="569" width="11" height="12" font="18">O</text>
<text top="421" left="580" width="5" height="12" font="31">(</text>
<text top="421" left="586" width="12" height="12" font="18">m</text>
<text top="418" left="598" width="6" height="8" font="19">k</text>
<text top="421" left="605" width="5" height="12" font="31">)</text>
<text top="421" left="614" width="220" height="12" font="4">copies of the innermost loop. As long as</text>
<text top="436" left="476" width="12" height="12" font="18">m</text>
<text top="436" left="491" width="289" height="12" font="4">is close to 1, the resulting trace trees will be tractable.</text>
<text top="451" left="493" width="341" height="12" font="4">An important detail is that the call to the inner trace tree must act</text>
<text top="466" left="476" width="359" height="12" font="4">like a function call site: it must return to the same point every time.</text>
<text top="481" left="476" width="359" height="12" font="4">The goal of nesting is to make inner and outer loops independent;</text>
<text top="496" left="476" width="359" height="12" font="4">thus when the inner tree is called, it must exit to the same point</text>
<text top="511" left="476" width="359" height="12" font="4">in the outer tree every time with the same type map. Because we</text>
<text top="526" left="476" width="359" height="12" font="4">cannot actually guarantee this property, we must guard on it after</text>
<text top="541" left="476" width="359" height="12" font="4">the call, and side exit if the property does not hold. A common</text>
<text top="556" left="476" width="359" height="12" font="4">reason for the inner tree not to return to the same point would</text>
<text top="571" left="476" width="359" height="12" font="4">be if the inner tree took a new side exit for which it had never</text>
<text top="586" left="476" width="359" height="12" font="4">compiled a trace. At this point, the interpreter PC is in the inner</text>
<text top="601" left="476" width="359" height="12" font="4">tree, so we cannot continue recording or executing the outer tree.</text>
<text top="616" left="476" width="359" height="12" font="4">If this happens during recording, we abort the outer trace, to give</text>
<text top="630" left="476" width="359" height="12" font="4">the inner tree a chance to finish growing. A future execution of the</text>
<text top="645" left="476" width="359" height="12" font="4">outer tree would then be able to properly finish and record a call to</text>
<text top="660" left="476" width="359" height="12" font="4">the inner tree. If an inner tree side exit happens during execution of</text>
<text top="675" left="476" width="359" height="12" font="4">a compiled trace for the outer tree, we simply exit the outer trace</text>
<text top="690" left="476" width="267" height="12" font="4">and start recording a new branch in the inner tree.</text>
<text top="723" left="476" width="17" height="12" font="15">4.2</text>
<text top="723" left="506" width="143" height="12" font="15">Blacklisting with Nesting</text>
<text top="744" left="476" width="359" height="12" font="4">The blacklisting algorithm needs modification to work well with</text>
<text top="759" left="476" width="359" height="12" font="4">nesting. The problem is that outer loop traces often abort during</text>
<text top="774" left="476" width="359" height="12" font="4">startup (because the inner tree is not available or takes a side exit),</text>
<text top="788" left="476" width="359" height="12" font="4">which would lead to their being quickly blacklisted by the basic</text>
<text top="803" left="476" width="56" height="12" font="4">algorithm.</text>
<text top="818" left="493" width="341" height="12" font="4">The key observation is that when an outer trace aborts because</text>
<text top="833" left="476" width="359" height="12" font="4">the inner tree is not ready, this is probably a temporary condition.</text>
<text top="848" left="476" width="359" height="12" font="4">Thus, we should not count such aborts toward blacklisting as long</text>
<text top="863" left="476" width="300" height="12" font="4">as we are able to build up more traces for the inner tree.</text>
<text top="878" left="493" width="341" height="12" font="4">In our implementation, when an outer tree aborts on the inner</text>
<text top="893" left="476" width="359" height="12" font="4">tree, we increment the outer tree’s blacklist counter as usual and</text>
<text top="908" left="476" width="359" height="12" font="4">back off on compiling it. When the inner tree finishes a trace, we</text>
<text top="923" left="476" width="359" height="12" font="4">decrement the blacklist counter on the outer loop, “forgiving” the</text>
<text top="938" left="476" width="359" height="12" font="4">outer loop for aborting previously. We also undo the backoff so that</text>
<text top="953" left="476" width="359" height="12" font="4">the outer tree can start immediately trying to compile the next time</text>
<text top="968" left="476" width="62" height="12" font="4">we reach it.</text>
<text top="1008" left="476" width="12" height="15" font="9">5.</text>
<text top="1008" left="504" width="173" height="15" font="9">Trace Tree Optimization</text>
<text top="1031" left="476" width="359" height="12" font="4">This section explains how a recorded trace is translated to an</text>
<text top="1046" left="476" width="359" height="12" font="4">optimized machine code trace. The trace compilation subsystem,</text>
<text top="1063" left="476" width="49" height="10" font="35">NANOJIT</text>
<text top="1061" left="525" width="309" height="12" font="4">, is separate from the VM and can be used for other</text>
<text top="1076" left="476" width="68" height="12" font="4">applications.</text>
</page>
<page number="8" position="absolute" top="0" left="0" height="1188" width="918">
<text top="111" left="81" width="17" height="12" font="15">5.1</text>
<text top="111" left="111" width="81" height="12" font="15">Optimizations</text>
<text top="132" left="81" width="340" height="12" font="4">Because traces are in SSA form and have no join points or</text>
<text top="132" left="427" width="8" height="12" font="18">φ</text>
<text top="132" left="435" width="4" height="12" font="4">-</text>
<text top="147" left="81" width="359" height="12" font="4">nodes, certain optimizations are easy to implement. In order to</text>
<text top="162" left="81" width="359" height="12" font="4">get good startup performance, the optimizations must run quickly,</text>
<text top="177" left="81" width="359" height="12" font="4">so we chose a small set of optimizations. We implemented the</text>
<text top="192" left="81" width="359" height="12" font="4">optimizations as pipelined filters so that they can be turned on and</text>
<text top="206" left="81" width="359" height="12" font="4">off independently, and yet all run in just two loop passes over the</text>
<text top="221" left="81" width="203" height="12" font="4">trace: one forward and one backward.</text>
<text top="236" left="99" width="341" height="12" font="4">Every time the trace recorder emits a LIR instruction, the in-</text>
<text top="251" left="81" width="359" height="12" font="4">struction is immediately passed to the first filter in the forward</text>
<text top="266" left="81" width="359" height="12" font="4">pipeline. Thus, forward filter optimizations are performed as the</text>
<text top="281" left="81" width="359" height="12" font="4">trace is recorded. Each filter may pass each instruction to the next</text>
<text top="296" left="81" width="359" height="12" font="4">filter unchanged, write a different instruction to the next filter, or</text>
<text top="311" left="81" width="359" height="12" font="4">write no instruction at all. For example, the constant folding filter</text>
<text top="326" left="81" width="207" height="12" font="4">can replace a multiply instruction like</text>
<text top="326" left="293" width="7" height="12" font="18">v</text>
<text top="330" left="299" width="11" height="8" font="8">13</text>
<text top="326" left="316" width="15" height="12" font="31">:=</text>
<text top="326" left="336" width="24" height="12" font="18">mul</text>
<text top="326" left="361" width="7" height="12" font="31">3</text>
<text top="326" left="368" width="4" height="12" font="18">,</text>
<text top="326" left="374" width="28" height="12" font="31">1000</text>
<text top="326" left="406" width="34" height="12" font="4">with a</text>
<text top="341" left="81" width="106" height="12" font="4">constant instruction</text>
<text top="341" left="190" width="7" height="12" font="18">v</text>
<text top="345" left="197" width="11" height="8" font="8">13</text>
<text top="341" left="212" width="42" height="12" font="31">= 3000</text>
<text top="341" left="255" width="3" height="12" font="4">.</text>
<text top="356" left="99" width="212" height="12" font="4">We currently apply four forward filters:</text>
<text top="381" left="89" width="6" height="11" font="2">•</text>
<text top="382" left="100" width="339" height="12" font="4">On ISAs without floating-point instructions, a soft-float filter</text>
<text top="397" left="100" width="339" height="12" font="4">converts floating-point LIR instructions to sequences of integer</text>
<text top="412" left="100" width="66" height="12" font="4">instructions.</text>
<text top="432" left="89" width="6" height="11" font="2">•</text>
<text top="433" left="100" width="229" height="12" font="4">CSE (constant subexpression elimination),</text>
<text top="452" left="89" width="6" height="11" font="2">•</text>
<text top="454" left="100" width="339" height="12" font="4">expression simplification, including constant folding and a few</text>
<text top="469" left="100" width="133" height="12" font="4">algebraic identities (e.g.,</text>
<text top="468" left="236" width="7" height="12" font="18">a</text>
<text top="468" left="247" width="11" height="13" font="6">−</text>
<text top="468" left="261" width="7" height="12" font="18">a</text>
<text top="468" left="272" width="22" height="12" font="31">= 0</text>
<text top="469" left="293" width="31" height="12" font="4">), and</text>
<text top="488" left="89" width="6" height="11" font="2">•</text>
<text top="490" left="100" width="339" height="12" font="4">source language semantic-specific expression simplification,</text>
<text top="504" left="100" width="211" height="12" font="4">primarily algebraic identities that allow</text>
<text top="506" left="314" width="47" height="10" font="35">DOUBLE</text>
<text top="504" left="365" width="75" height="12" font="4">to be replaced</text>
<text top="519" left="100" width="24" height="12" font="4">with</text>
<text top="521" left="128" width="19" height="10" font="35">INT</text>
<text top="519" left="148" width="193" height="12" font="4">. For example, LIR that converts an</text>
<text top="521" left="345" width="19" height="10" font="35">INT</text>
<text top="519" left="368" width="20" height="12" font="4">to a</text>
<text top="521" left="392" width="47" height="10" font="35">DOUBLE</text>
<text top="534" left="100" width="281" height="12" font="4">and then back again would be removed by this filter.</text>
<text top="560" left="99" width="341" height="12" font="4">When trace recording is completed, nanojit runs the backward</text>
<text top="575" left="81" width="359" height="12" font="4">optimization filters. These are used for optimizations that require</text>
<text top="590" left="81" width="359" height="12" font="4">backward program analysis. When running the backward filters,</text>
<text top="605" left="81" width="359" height="12" font="4">nanojit reads one LIR instruction at a time, and the reads are passed</text>
<text top="620" left="81" width="112" height="12" font="4">through the pipeline.</text>
<text top="635" left="99" width="226" height="12" font="4">We currently apply three backward filters:</text>
<text top="660" left="89" width="6" height="11" font="2">•</text>
<text top="661" left="100" width="339" height="12" font="4">Dead data-stack store elimination. The LIR trace encodes many</text>
<text top="676" left="100" width="339" height="12" font="4">stores to locations in the interpreter stack. But these values are</text>
<text top="691" left="100" width="339" height="12" font="4">never read back before exiting the trace (by the interpreter or</text>
<text top="706" left="100" width="339" height="12" font="4">another trace). Thus, stores to the stack that are overwritten</text>
<text top="721" left="100" width="339" height="12" font="4">before the next exit are dead. Stores to locations that are off</text>
<text top="736" left="100" width="316" height="12" font="4">the top of the interpreter stack at future exits are also dead.</text>
<text top="756" left="89" width="6" height="11" font="2">•</text>
<text top="757" left="100" width="339" height="12" font="4">Dead call-stack store elimination. This is the same optimization</text>
<text top="772" left="100" width="339" height="12" font="4">as above, except applied to the interpreter’s call stack used for</text>
<text top="787" left="100" width="116" height="12" font="4">function call inlining.</text>
<text top="806" left="89" width="6" height="11" font="2">•</text>
<text top="808" left="100" width="339" height="12" font="4">Dead code elimination. This eliminates any operation that</text>
<text top="822" left="100" width="187" height="12" font="4">stores to a value that is never used.</text>
<text top="848" left="99" width="341" height="12" font="4">After a LIR instruction is successfully read (“pulled”) from</text>
<text top="863" left="81" width="359" height="12" font="4">the backward filter pipeline, nanojit’s code generator emits native</text>
<text top="878" left="81" width="154" height="12" font="4">machine instruction(s) for it.</text>
<text top="906" left="81" width="17" height="12" font="15">5.2</text>
<text top="906" left="111" width="110" height="12" font="15">Register Allocation</text>
<text top="927" left="81" width="359" height="12" font="4">We use a simple greedy register allocator that makes a single</text>
<text top="942" left="81" width="359" height="12" font="4">backward pass over the trace (it is integrated with the code gen-</text>
<text top="957" left="81" width="359" height="12" font="4">erator). By the time the allocator has reached an instruction like</text>
<text top="971" left="81" width="7" height="12" font="18">v</text>
<text top="976" left="88" width="5" height="8" font="8">3</text>
<text top="971" left="98" width="11" height="12" font="31">=</text>
<text top="971" left="113" width="32" height="12" font="18">add v</text>
<text top="976" left="145" width="5" height="8" font="8">1</text>
<text top="971" left="152" width="13" height="12" font="18">, v</text>
<text top="976" left="165" width="5" height="8" font="8">2</text>
<text top="972" left="171" width="197" height="12" font="4">, it has already assigned a register to</text>
<text top="971" left="371" width="7" height="12" font="18">v</text>
<text top="976" left="378" width="5" height="8" font="8">3</text>
<text top="972" left="384" width="16" height="12" font="4">. If</text>
<text top="971" left="404" width="7" height="12" font="18">v</text>
<text top="976" left="410" width="5" height="8" font="8">1</text>
<text top="972" left="420" width="19" height="12" font="4">and</text>
<text top="986" left="81" width="7" height="12" font="18">v</text>
<text top="991" left="88" width="5" height="8" font="8">2</text>
<text top="987" left="97" width="342" height="12" font="4">have not yet been assigned registers, the allocator assigns a free</text>
<text top="1001" left="81" width="359" height="12" font="4">register to each. If there are no free registers, a value is selected for</text>
<text top="1016" left="81" width="359" height="12" font="4">spilling. We use a class heuristic that selects the “oldest” register-</text>
<text top="1031" left="81" width="92" height="12" font="4">carried value (6).</text>
<text top="1046" left="99" width="163" height="12" font="4">The heuristic considers the set</text>
<text top="1046" left="265" width="10" height="12" font="18">R</text>
<text top="1046" left="279" width="49" height="12" font="4">of values</text>
<text top="1046" left="331" width="7" height="12" font="18">v</text>
<text top="1046" left="342" width="98" height="12" font="4">in registers imme-</text>
<text top="1061" left="81" width="278" height="12" font="4">diately after the current instruction for spilling. Let</text>
<text top="1061" left="363" width="7" height="12" font="18">v</text>
<text top="1066" left="370" width="10" height="8" font="19">m</text>
<text top="1061" left="384" width="56" height="12" font="4">be the last</text>
<text top="1076" left="81" width="221" height="12" font="4">instruction before the current where each</text>
<text top="1076" left="306" width="7" height="12" font="18">v</text>
<text top="1076" left="316" width="123" height="12" font="4">is referred to. Then the</text>
<text top="109" left="485" width="20" height="12" font="4">Tag</text>
<text top="109" left="523" width="43" height="12" font="4">JS Type</text>
<text top="109" left="594" width="63" height="12" font="4">Description</text>
<text top="125" left="485" width="20" height="12" font="4">xx1</text>
<text top="125" left="523" width="41" height="12" font="4">number</text>
<text top="125" left="594" width="152" height="12" font="4">31-bit integer representation</text>
<text top="140" left="485" width="20" height="12" font="4">000</text>
<text top="140" left="523" width="33" height="12" font="4">object</text>
<text top="140" left="594" width="143" height="12" font="4">pointer to JSObject handle</text>
<text top="155" left="485" width="20" height="12" font="4">010</text>
<text top="155" left="523" width="41" height="12" font="4">number</text>
<text top="155" left="594" width="131" height="12" font="4">pointer to double handle</text>
<text top="170" left="485" width="20" height="12" font="4">100</text>
<text top="170" left="523" width="31" height="12" font="4">string</text>
<text top="170" left="594" width="140" height="12" font="4">pointer to JSString handle</text>
<text top="185" left="485" width="20" height="12" font="4">110</text>
<text top="185" left="523" width="43" height="12" font="4">boolean</text>
<text top="185" left="594" width="230" height="12" font="4">enumeration for null, undefined, true, false</text>
<text top="200" left="523" width="39" height="12" font="4">null, or</text>
<text top="215" left="523" width="53" height="12" font="4">undefined</text>
<text top="241" left="476" width="359" height="12" font="15">Figure 9. Tagged values in the SpiderMonkey JS interpreter.</text>
<text top="256" left="476" width="359" height="12" font="4">Testing tags, unboxing (extracting the untagged value) and boxing</text>
<text top="271" left="476" width="359" height="12" font="4">(creating tagged values) are significant costs. Avoiding these costs</text>
<text top="286" left="476" width="139" height="12" font="4">is a key benefit of tracing.</text>
<text top="341" left="476" width="87" height="12" font="4">heuristic selects</text>
<text top="341" left="567" width="7" height="12" font="18">v</text>
<text top="341" left="578" width="81" height="12" font="4">with minimum</text>
<text top="341" left="664" width="7" height="12" font="18">v</text>
<text top="346" left="670" width="10" height="8" font="19">m</text>
<text top="341" left="681" width="153" height="12" font="4">. The motivation is that this</text>
<text top="356" left="476" width="326" height="12" font="4">frees up a register for as long as possible given a single spill.</text>
<text top="371" left="493" width="152" height="12" font="4">If we need to spill a value</text>
<text top="371" left="651" width="7" height="12" font="18">v</text>
<text top="375" left="657" width="5" height="8" font="19">s</text>
<text top="371" left="669" width="165" height="12" font="4">at this point, we generate the</text>
<text top="386" left="476" width="359" height="12" font="4">restore code just after the code for the current instruction. The</text>
<text top="401" left="476" width="359" height="12" font="4">corresponding spill code is generated just after the last point where</text>
<text top="416" left="476" width="7" height="12" font="18">v</text>
<text top="420" left="482" width="5" height="8" font="19">s</text>
<text top="416" left="491" width="229" height="12" font="4">was used. The register that was assigned to</text>
<text top="416" left="723" width="7" height="12" font="18">v</text>
<text top="420" left="730" width="5" height="8" font="19">s</text>
<text top="416" left="739" width="95" height="12" font="4">is marked free for</text>
<text top="431" left="476" width="359" height="12" font="4">the preceding code, because that register can now be used freely</text>
<text top="446" left="476" width="196" height="12" font="4">without affecting the following code</text>
<text top="481" left="476" width="12" height="15" font="9">6.</text>
<text top="481" left="504" width="112" height="15" font="9">Implementation</text>
<text top="504" left="476" width="359" height="12" font="4">To demonstrate the effectiveness of our approach, we have im-</text>
<text top="519" left="476" width="359" height="12" font="4">plemented a trace-based dynamic compiler for the SpiderMonkey</text>
<text top="534" left="476" width="359" height="12" font="4">JavaScript Virtual Machine (4). SpiderMonkey is the JavaScript</text>
<text top="548" left="476" width="359" height="12" font="4">VM embedded in Mozilla’s Firefox open-source web browser (2),</text>
<text top="563" left="476" width="359" height="12" font="4">which is used by more than 200 million users world-wide. The core</text>
<text top="578" left="476" width="345" height="12" font="4">of SpiderMonkey is a bytecode interpreter implemented in C++.</text>
<text top="593" left="493" width="341" height="12" font="4">In SpiderMonkey, all JavaScript values are represented by the</text>
<text top="608" left="476" width="23" height="12" font="4">type</text>
<text top="609" left="502" width="35" height="11" font="7">jsval</text>
<text top="608" left="538" width="17" height="12" font="4">. A</text>
<text top="609" left="558" width="35" height="11" font="7">jsval</text>
<text top="608" left="597" width="237" height="12" font="4">is machine word in which up to the 3 of the</text>
<text top="623" left="476" width="359" height="12" font="4">least significant bits are a type tag, and the remaining bits are data.</text>
<text top="638" left="476" width="267" height="12" font="4">See Figure 6 for details. All pointers contained in</text>
<text top="639" left="747" width="42" height="11" font="7">jsvals</text>
<text top="638" left="792" width="42" height="12" font="4">point to</text>
<text top="653" left="476" width="279" height="12" font="4">GC-controlled blocks aligned on 8-byte boundaries.</text>
<text top="668" left="493" width="55" height="12" font="4">JavaScript</text>
<text top="668" left="552" width="33" height="12" font="11">object</text>
<text top="668" left="588" width="246" height="12" font="4">values are mappings of string-valued property</text>
<text top="683" left="476" width="359" height="12" font="4">names to arbitrary values. They are represented in one of two ways</text>
<text top="698" left="476" width="359" height="12" font="4">in SpiderMonkey. Most objects are represented by a shared struc-</text>
<text top="713" left="476" width="145" height="12" font="4">tural description, called the</text>
<text top="713" left="624" width="67" height="12" font="11">object shape</text>
<text top="713" left="691" width="144" height="12" font="4">, that maps property names</text>
<text top="728" left="476" width="359" height="12" font="4">to array indexes using a hash table. The object stores a pointer to</text>
<text top="743" left="476" width="359" height="12" font="4">the shape and the array of its own property values. Objects with</text>
<text top="758" left="476" width="359" height="12" font="4">large, unique sets of property names store their properties directly</text>
<text top="773" left="476" width="81" height="12" font="4">in a hash table.</text>
<text top="788" left="493" width="341" height="12" font="4">The garbage collector is an exact, non-generational, stop-the-</text>
<text top="803" left="476" width="177" height="12" font="4">world mark-and-sweep collector.</text>
<text top="817" left="493" width="341" height="12" font="4">In the rest of this section we discuss key areas of the TraceMon-</text>
<text top="832" left="476" width="110" height="12" font="4">key implementation.</text>
<text top="861" left="476" width="17" height="12" font="15">6.1</text>
<text top="861" left="506" width="142" height="12" font="15">Calling Compiled Traces</text>
<text top="882" left="476" width="170" height="12" font="4">Compiled traces are stored in a</text>
<text top="882" left="649" width="63" height="12" font="11">trace cache</text>
<text top="882" left="712" width="122" height="12" font="4">, indexed by intepreter</text>
<text top="897" left="476" width="359" height="12" font="4">PC and type map. Traces are compiled so that they may be</text>
<text top="912" left="476" width="359" height="12" font="4">called as functions using standard native calling conventions (e.g.,</text>
<text top="928" left="476" width="56" height="11" font="7">FASTCALL</text>
<text top="927" left="535" width="45" height="12" font="4">on x86).</text>
<text top="942" left="493" width="341" height="12" font="4">The interpreter must hit a loop edge and enter the monitor in</text>
<text top="957" left="476" width="359" height="12" font="4">order to call a native trace for the first time. The monitor computes</text>
<text top="972" left="476" width="359" height="12" font="4">the current type map, checks the trace cache for a trace for the</text>
<text top="987" left="476" width="340" height="12" font="4">current PC and type map, and if it finds one, executes the trace.</text>
<text top="1001" left="493" width="341" height="12" font="4">To execute a trace, the monitor must build a trace activation</text>
<text top="1016" left="476" width="359" height="12" font="4">record containing imported local and global variables, temporary</text>
<text top="1031" left="476" width="359" height="12" font="4">stack space, and space for arguments to native calls. The local and</text>
<text top="1046" left="476" width="359" height="12" font="4">global values are then copied from the interpreter state to the trace</text>
<text top="1061" left="476" width="359" height="12" font="4">activation record. Then, the trace is called like a normal C function</text>
<text top="1076" left="476" width="41" height="12" font="4">pointer.</text>
</page>
<page number="9" position="absolute" top="0" left="0" height="1188" width="918">
<text top="111" left="99" width="341" height="12" font="4">When a trace call returns, the monitor restores the interpreter</text>
<text top="126" left="81" width="359" height="12" font="4">state. First, the monitor checks the reason for the trace exit and</text>
<text top="141" left="81" width="359" height="12" font="4">applies blacklisting if needed. Then, it pops or synthesizes inter-</text>
<text top="156" left="81" width="359" height="12" font="4">preter JavaScript call stack frames as needed. Finally, it copies the</text>
<text top="171" left="81" width="359" height="12" font="4">imported variables back from the trace activation record to the in-</text>
<text top="186" left="81" width="77" height="12" font="4">terpreter state.</text>
<text top="201" left="99" width="341" height="12" font="4">At least in the current implementation, these steps have a non-</text>
<text top="215" left="81" width="359" height="12" font="4">negligible runtime cost, so minimizing the number of interpreter-</text>
<text top="230" left="81" width="359" height="12" font="4">to-trace and trace-to-interpreter transitions is essential for perfor-</text>
<text top="245" left="81" width="359" height="12" font="4">mance. (see also Section 3.3). Our experiments (see Figure 12)</text>
<text top="260" left="81" width="359" height="12" font="4">show that for programs we can trace well such transitions hap-</text>
<text top="275" left="81" width="359" height="12" font="4">pen infrequently and hence do not contribute significantly to total</text>
<text top="290" left="81" width="359" height="12" font="4">runtime. In a few programs, where the system is prevented from</text>
<text top="305" left="81" width="359" height="12" font="4">recording branch traces for hot side exits by aborts, this cost can</text>
<text top="320" left="81" width="220" height="12" font="4">rise to up to 10% of total execution time.</text>
<text top="348" left="81" width="17" height="12" font="15">6.2</text>
<text top="348" left="111" width="88" height="12" font="15">Trace Stitching</text>
<text top="369" left="81" width="359" height="12" font="4">Transitions from a trace to a branch trace at a side exit avoid the</text>
<text top="384" left="81" width="327" height="12" font="4">costs of calling traces from the monitor, in a feature called</text>
<text top="384" left="412" width="27" height="12" font="11">trace</text>
<text top="399" left="81" width="46" height="12" font="11">stitching</text>
<text top="399" left="127" width="313" height="12" font="4">. At a side exit, the exiting trace only needs to write live</text>
<text top="414" left="81" width="359" height="12" font="4">register-carried values back to its trace activation record. In our im-</text>
<text top="429" left="81" width="359" height="12" font="4">plementation, identical type maps yield identical activation record</text>
<text top="444" left="81" width="359" height="12" font="4">layouts, so the trace activation record can be reused immediately</text>
<text top="459" left="81" width="106" height="12" font="4">by the branch trace.</text>
<text top="474" left="99" width="341" height="12" font="4">In programs with branchy trace trees with small traces, trace</text>
<text top="489" left="81" width="359" height="12" font="4">stitching has a noticeable cost. Although writing to memory and</text>
<text top="504" left="81" width="359" height="12" font="4">then soon reading back would be expected to have a high L1</text>
<text top="519" left="81" width="359" height="12" font="4">cache hit rate, for small traces the increased instruction count has</text>
<text top="534" left="81" width="359" height="12" font="4">a noticeable cost. Also, if the writes and reads are very close</text>
<text top="549" left="81" width="359" height="12" font="4">in the dynamic instruction stream, we have found that current</text>
<text top="564" left="81" width="359" height="12" font="4">x86 processors often incur penalties of 6 cycles or more (e.g., if</text>
<text top="579" left="81" width="359" height="12" font="4">the instructions use different base registers with equal values, the</text>
<text top="594" left="81" width="359" height="12" font="4">processor may not be able to detect that the addresses are the same</text>
<text top="608" left="81" width="65" height="12" font="4">right away).</text>
<text top="623" left="99" width="341" height="12" font="4">The alternate solution is to recompile an entire trace tree, thus</text>
<text top="638" left="81" width="359" height="12" font="4">achieving inter-trace register allocation (10). The disadvantage is</text>
<text top="653" left="81" width="359" height="12" font="4">that tree recompilation takes time quadratic in the number of traces.</text>
<text top="668" left="81" width="359" height="12" font="4">We believe that the cost of recompiling a trace tree every time</text>
<text top="683" left="81" width="359" height="12" font="4">a branch is added would be prohibitive. That problem might be</text>
<text top="698" left="81" width="359" height="12" font="4">mitigated by recompiling only at certain points, or only for very</text>
<text top="713" left="81" width="87" height="12" font="4">hot, stable trees.</text>
<text top="728" left="99" width="341" height="12" font="4">In the future, multicore hardware is expected to be common,</text>
<text top="743" left="81" width="359" height="12" font="4">making background tree recompilation attractive. In a closely re-</text>
<text top="758" left="81" width="359" height="12" font="4">lated project (13) background recompilation yielded speedups of</text>
<text top="773" left="81" width="359" height="12" font="4">up to 1.25x on benchmarks with many branch traces. We plan to</text>
<text top="788" left="81" width="284" height="12" font="4">apply this technique to TraceMonkey as future work.</text>
<text top="816" left="81" width="17" height="12" font="15">6.3</text>
<text top="816" left="111" width="96" height="12" font="15">Trace Recording</text>
<text top="837" left="81" width="359" height="12" font="4">The job of the trace recorder is to emit LIR with identical semantics</text>
<text top="852" left="81" width="359" height="12" font="4">to the currently running interpreter bytecode trace. A good imple-</text>
<text top="867" left="81" width="359" height="12" font="4">mentation should have low impact on non-tracing interpreter per-</text>
<text top="882" left="81" width="359" height="12" font="4">formance and a convenient way for implementers to maintain se-</text>
<text top="897" left="81" width="107" height="12" font="4">mantic equivalence.</text>
<text top="912" left="99" width="341" height="12" font="4">In our implementation, the only direct modification to the inter-</text>
<text top="927" left="81" width="359" height="12" font="4">preter is a call to the trace monitor at loop edges. In our benchmark</text>
<text top="942" left="81" width="359" height="12" font="4">results (see Figure 12) the total time spent in the monitor (for all</text>
<text top="957" left="81" width="359" height="12" font="4">activities) is usually less than 5%, so we consider the interpreter</text>
<text top="972" left="81" width="359" height="12" font="4">impact requirement met. Incrementing the loop hit counter is ex-</text>
<text top="987" left="81" width="359" height="12" font="4">pensive because it requires us to look up the loop in the trace cache,</text>
<text top="1001" left="81" width="359" height="12" font="4">but we have tuned our loops to become hot and trace very quickly</text>
<text top="1016" left="81" width="359" height="12" font="4">(on the second iteration). The hit counter implementation could be</text>
<text top="1031" left="81" width="359" height="12" font="4">improved, which might give us a small increase in overall perfor-</text>
<text top="1046" left="81" width="359" height="12" font="4">mance, as well as more flexibility with tuning hotness thresholds.</text>
<text top="1061" left="81" width="359" height="12" font="4">Once a loop is blacklisted we never call into the trace monitor for</text>
<text top="1076" left="81" width="144" height="12" font="4">that loop (see Section 3.3).</text>
<text top="111" left="493" width="341" height="12" font="4">Recording is activated by a pointer swap that sets the inter-</text>
<text top="126" left="476" width="359" height="12" font="4">preter’s dispatch table to call a single “interrupt” routine for ev-</text>
<text top="141" left="476" width="359" height="12" font="4">ery bytecode. The interrupt routine first calls a bytecode-specific</text>
<text top="156" left="476" width="359" height="12" font="4">recording routine. Then, it turns off recording if necessary (e.g.,</text>
<text top="171" left="476" width="359" height="12" font="4">the trace ended). Finally, it jumps to the standard interpreter byte-</text>
<text top="186" left="476" width="359" height="12" font="4">code implementation. Some bytecodes have effects on the type map</text>
<text top="201" left="476" width="359" height="12" font="4">that cannot be predicted before executing the bytecode (e.g., call-</text>
<text top="215" left="476" width="17" height="12" font="4">ing</text>
<text top="216" left="497" width="120" height="11" font="7">String.charCodeAt</text>
<text top="215" left="617" width="155" height="12" font="4">, which returns an integer or</text>
<text top="216" left="776" width="25" height="12" font="11">NaN</text>
<text top="215" left="805" width="29" height="12" font="4">if the</text>
<text top="230" left="476" width="359" height="12" font="4">index argument is out of range). For these, we arrange for the inter-</text>
<text top="245" left="476" width="359" height="12" font="4">preter to call into the recorder again after executing the bytecode.</text>
<text top="260" left="476" width="359" height="12" font="4">Since such hooks are relatively rare, we embed them directly into</text>
<text top="275" left="476" width="359" height="12" font="4">the interpreter, with an additional runtime check to see whether a</text>
<text top="290" left="476" width="147" height="12" font="4">recorder is currently active.</text>
<text top="305" left="493" width="341" height="12" font="4">While separating the interpreter from the recorder reduces indi-</text>
<text top="320" left="476" width="359" height="12" font="4">vidual code complexity, it also requires careful implementation and</text>
<text top="335" left="476" width="268" height="12" font="4">extensive testing to achieve semantic equivalence.</text>
<text top="350" left="493" width="341" height="12" font="4">In some cases achieving this equivalence is difficult since Spi-</text>
<text top="365" left="476" width="116" height="12" font="4">derMonkey follows a</text>
<text top="365" left="596" width="66" height="12" font="11">fat-bytecode</text>
<text top="365" left="666" width="168" height="12" font="4">design, which was found to be</text>
<text top="380" left="476" width="227" height="12" font="4">beneficial to pure interpreter performance.</text>
<text top="395" left="493" width="341" height="12" font="4">In fat-bytecode designs, individual bytecodes can implement</text>
<text top="410" left="476" width="165" height="12" font="4">complex processing (e.g., the</text>
<text top="411" left="647" width="49" height="11" font="7">getprop</text>
<text top="410" left="702" width="132" height="12" font="4">bytecode, which imple-</text>
<text top="425" left="476" width="359" height="12" font="4">ments full JavaScript property value access, including special cases</text>
<text top="440" left="476" width="190" height="12" font="4">for cached and dense array access).</text>
<text top="455" left="493" width="341" height="12" font="4">Fat bytecodes have two advantages: fewer bytecodes means</text>
<text top="469" left="476" width="359" height="12" font="4">lower dispatch cost, and bigger bytecode implementations give the</text>
<text top="484" left="476" width="299" height="12" font="4">compiler more opportunities to optimize the interpreter.</text>
<text top="499" left="493" width="341" height="12" font="4">Fat bytecodes are a problem for TraceMonkey because they</text>
<text top="514" left="476" width="359" height="12" font="4">require the recorder to reimplement the same special case logic</text>
<text top="529" left="476" width="359" height="12" font="4">in the same way. Also, the advantages are reduced because (a)</text>
<text top="544" left="476" width="359" height="12" font="4">dispatch costs are eliminated entirely in compiled traces, (b) the</text>
<text top="559" left="476" width="359" height="12" font="4">traces contain only one special case, not the interpreter’s large</text>
<text top="574" left="476" width="359" height="12" font="4">chunk of code, and (c) TraceMonkey spends less time running the</text>
<text top="589" left="476" width="86" height="12" font="4">base interpreter.</text>
<text top="604" left="493" width="341" height="12" font="4">One way we have mitigated these problems is by implementing</text>
<text top="619" left="476" width="359" height="12" font="4">certain complex bytecodes in the recorder as sequences of simple</text>
<text top="634" left="476" width="359" height="12" font="4">bytecodes. Expressing the original semantics this way is not too dif-</text>
<text top="649" left="476" width="359" height="12" font="4">ficult, and recording simple bytecodes is much easier. This enables</text>
<text top="664" left="476" width="359" height="12" font="4">us to retain the advantages of fat bytecodes while avoiding some of</text>
<text top="679" left="476" width="359" height="12" font="4">their problems for trace recording. This is particularly effective for</text>
<text top="694" left="476" width="359" height="12" font="4">fat bytecodes that recurse back into the interpreter, for example to</text>
<text top="709" left="476" width="359" height="12" font="4">convert an object into a primitive value by invoking a well-known</text>
<text top="724" left="476" width="327" height="12" font="4">method on the object, since it lets us inline this function call.</text>
<text top="738" left="493" width="341" height="12" font="4">It is important to note that we split fat opcodes into thinner op-</text>
<text top="753" left="476" width="359" height="12" font="4">codes only during recording. When running purely interpretatively</text>
<text top="768" left="476" width="359" height="12" font="4">(i.e. code that has been blacklisted), the interpreter directly and ef-</text>
<text top="783" left="476" width="181" height="12" font="4">ficiently executes the fat opcodes.</text>
<text top="831" left="476" width="17" height="12" font="15">6.4</text>
<text top="831" left="506" width="67" height="12" font="15">Preemption</text>
<text top="852" left="476" width="359" height="12" font="4">SpiderMonkey, like many VMs, needs to preempt the user program</text>
<text top="867" left="476" width="359" height="12" font="4">periodically. The main reasons are to prevent infinitely looping</text>
<text top="882" left="476" width="324" height="12" font="4">scripts from locking up the host system and to schedule GC.</text>
<text top="897" left="493" width="341" height="12" font="4">In the interpreter, this had been implemented by setting a “pre-</text>
<text top="912" left="476" width="359" height="12" font="4">empt now” flag that was checked on every backward jump. This</text>
<text top="927" left="476" width="359" height="12" font="4">strategy carried over into TraceMonkey: the VM inserts a guard on</text>
<text top="942" left="476" width="359" height="12" font="4">the preemption flag at every loop edge. We measured less than a</text>
<text top="957" left="476" width="359" height="12" font="4">1% increase in runtime on most benchmarks for this extra guard.</text>
<text top="972" left="476" width="359" height="12" font="4">In practice, the cost is detectable only for programs with very short</text>
<text top="987" left="476" width="33" height="12" font="4">loops.</text>
<text top="1001" left="493" width="341" height="12" font="4">We tested and rejected a solution that avoided the guards by</text>
<text top="1016" left="476" width="359" height="12" font="4">compiling the loop edge as an unconditional jump, and patching</text>
<text top="1031" left="476" width="359" height="12" font="4">the jump target to an exit routine when preemption is required.</text>
<text top="1046" left="476" width="359" height="12" font="4">This solution can make the normal case slightly faster, but then</text>
<text top="1061" left="476" width="359" height="12" font="4">preemption becomes very slow. The implementation was also very</text>
<text top="1076" left="476" width="359" height="12" font="4">complex, especially trying to restart execution after the preemption.</text>
</page>
<page number="10" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="36" size="8" family="BTMOLE+Calibri" color="#000000"/>
	<fontspec id="37" size="7" family="BTMOLE+Calibri" color="#000000"/>
<text top="111" left="81" width="17" height="12" font="15">6.5</text>
<text top="111" left="111" width="155" height="12" font="15">Calling External Functions</text>
<text top="132" left="81" width="359" height="12" font="4">Like most interpreters, SpiderMonkey has a foreign function inter-</text>
<text top="147" left="81" width="359" height="12" font="4">face (FFI) that allows it to call C builtins and host system functions</text>
<text top="162" left="81" width="359" height="12" font="4">(e.g., web browser control and DOM access). The FFI has a stan-</text>
<text top="177" left="81" width="359" height="12" font="4">dard signature for JS-callable functions, the key argument of which</text>
<text top="192" left="81" width="359" height="12" font="4">is an array of boxed values. External functions called through the</text>
<text top="206" left="81" width="359" height="12" font="4">FFI interact with the program state through an interpreter API (e.g.,</text>
<text top="221" left="81" width="359" height="12" font="4">to read a property from an argument). There are also certain inter-</text>
<text top="236" left="81" width="359" height="12" font="4">preter builtins that do not use the FFI, but interact with the program</text>
<text top="251" left="81" width="191" height="12" font="4">state in the same way, such as the</text>
<text top="252" left="277" width="113" height="11" font="7">CallIteratorNext</text>
<text top="251" left="395" width="45" height="12" font="4">function</text>
<text top="266" left="81" width="359" height="12" font="4">used with iterator objects. TraceMonkey must support this FFI in</text>
<text top="281" left="81" width="359" height="12" font="4">order to speed up code that interacts with the host system inside hot</text>
<text top="296" left="81" width="33" height="12" font="4">loops.</text>
<text top="311" left="99" width="341" height="12" font="4">Calling external functions from TraceMonkey is potentially dif-</text>
<text top="326" left="81" width="359" height="12" font="4">ficult because traces do not update the interpreter state until exit-</text>
<text top="341" left="81" width="359" height="12" font="4">ing. In particular, external functions may need the call stack or the</text>
<text top="356" left="81" width="242" height="12" font="4">global variables, but they may be out of date.</text>
<text top="371" left="99" width="341" height="12" font="4">For the out-of-date call stack problem, we refactored some of</text>
<text top="386" left="81" width="359" height="12" font="4">the interpreter API implementation functions to re-materialize the</text>
<text top="401" left="81" width="176" height="12" font="4">interpreter call stack on demand.</text>
<text top="416" left="99" width="341" height="12" font="4">We developed a C++ static analysis and annotated some inter-</text>
<text top="431" left="81" width="359" height="12" font="4">preter functions in order to verify that the call stack is refreshed</text>
<text top="446" left="81" width="359" height="12" font="4">at any point it needs to be used. In order to access the call stack,</text>
<text top="461" left="81" width="236" height="12" font="4">a function must be annotated as either F</text>
<text top="462" left="317" width="37" height="10" font="35">ORCES</text>
<text top="461" left="355" width="7" height="12" font="4">S</text>
<text top="462" left="364" width="30" height="10" font="35">TACK</text>
<text top="461" left="400" width="27" height="12" font="4">or R</text>
<text top="462" left="428" width="7" height="10" font="35">E</text>
<text top="461" left="435" width="4" height="12" font="4">-</text>
<text top="477" left="81" width="42" height="10" font="35">QUIRES</text>
<text top="475" left="124" width="7" height="12" font="4">S</text>
<text top="477" left="132" width="30" height="10" font="35">TACK</text>
<text top="475" left="162" width="277" height="12" font="4">. These annotations are also required in order to call</text>
<text top="490" left="81" width="9" height="12" font="4">R</text>
<text top="492" left="91" width="49" height="10" font="35">EQUIRES</text>
<text top="490" left="141" width="7" height="12" font="4">S</text>
<text top="492" left="149" width="30" height="10" font="35">TACK</text>
<text top="490" left="182" width="257" height="12" font="4">functions, which are presumed to access the call</text>
<text top="505" left="81" width="107" height="12" font="4">stack transitively. F</text>
<text top="507" left="189" width="37" height="10" font="35">ORCES</text>
<text top="505" left="227" width="7" height="12" font="4">S</text>
<text top="507" left="235" width="30" height="10" font="35">TACK</text>
<text top="505" left="270" width="170" height="12" font="4">is a trusted annotation, applied</text>
<text top="520" left="81" width="359" height="12" font="4">to only 5 functions, that means the function refreshes the call stack.</text>
<text top="535" left="81" width="9" height="12" font="4">R</text>
<text top="537" left="91" width="49" height="10" font="35">EQUIRES</text>
<text top="535" left="141" width="7" height="12" font="4">S</text>
<text top="537" left="149" width="30" height="10" font="35">TACK</text>
<text top="535" left="183" width="256" height="12" font="4">is an untrusted annotation that means the func-</text>
<text top="550" left="81" width="359" height="12" font="4">tion may only be called if the call stack has already been refreshed.</text>
<text top="565" left="99" width="341" height="12" font="4">Similarly, we detect when host functions attempt to directly</text>
<text top="580" left="81" width="359" height="12" font="4">read or write global variables, and force the currently running trace</text>
<text top="595" left="81" width="359" height="12" font="4">to side exit. This is necessary since we cache and unbox global</text>
<text top="610" left="81" width="312" height="12" font="4">variables into the activation record during trace execution.</text>
<text top="625" left="99" width="341" height="12" font="4">Since both call-stack access and global variable access are</text>
<text top="640" left="81" width="359" height="12" font="4">rarely performed by host functions, performance is not significantly</text>
<text top="655" left="81" width="199" height="12" font="4">affected by these safety mechanisms.</text>
<text top="670" left="99" width="341" height="12" font="4">Another problem is that external functions can reenter the inter-</text>
<text top="685" left="81" width="359" height="12" font="4">preter by calling scripts, which in turn again might want to access</text>
<text top="700" left="81" width="359" height="12" font="4">the call stack or global variables. To address this problem, we made</text>
<text top="715" left="81" width="359" height="12" font="4">the VM set a flag whenever the interpreter is reentered while a com-</text>
<text top="730" left="81" width="117" height="12" font="4">piled trace is running.</text>
<text top="744" left="99" width="341" height="12" font="4">Every call to an external function then checks this flag and exits</text>
<text top="759" left="81" width="359" height="12" font="4">the trace immediately after returning from the external function call</text>
<text top="774" left="81" width="359" height="12" font="4">if it is set. There are many external functions that seldom or never</text>
<text top="789" left="81" width="359" height="12" font="4">reenter, and they can be called without problem, and will cause</text>
<text top="804" left="81" width="146" height="12" font="4">trace exit only if necessary.</text>
<text top="819" left="99" width="341" height="12" font="4">The FFI’s boxed value array requirement has a performance</text>
<text top="834" left="81" width="359" height="12" font="4">cost, so we defined a new FFI that allows C functions to be an-</text>
<text top="849" left="81" width="359" height="12" font="4">notated with their argument types so that the tracer can call them</text>
<text top="864" left="81" width="281" height="12" font="4">directly, without unnecessary argument conversions.</text>
<text top="879" left="99" width="341" height="12" font="4">Currently, we do not support calling native property get and set</text>
<text top="894" left="81" width="359" height="12" font="4">override functions or DOM functions directly from trace. Support</text>
<text top="909" left="81" width="125" height="12" font="4">is planned future work.</text>
<text top="936" left="81" width="17" height="12" font="15">6.6</text>
<text top="936" left="111" width="68" height="12" font="15">Correctness</text>
<text top="957" left="81" width="359" height="12" font="4">During development, we had access to existing JavaScript test</text>
<text top="972" left="81" width="359" height="12" font="4">suites, but most of them were not designed with tracing VMs in</text>
<text top="987" left="81" width="165" height="12" font="4">mind and contained few loops.</text>
<text top="1001" left="99" width="341" height="12" font="4">One tool that helped us greatly was Mozilla’s JavaScript fuzz</text>
<text top="1016" left="81" width="32" height="12" font="4">tester,</text>
<text top="1018" left="118" width="64" height="10" font="35">JSFUNFUZZ</text>
<text top="1016" left="182" width="258" height="12" font="4">, which generates random JavaScript programs</text>
<text top="1031" left="81" width="289" height="12" font="4">by nesting random language elements. We modified</text>
<text top="1033" left="375" width="64" height="10" font="35">JSFUNFUZZ</text>
<text top="1046" left="81" width="359" height="12" font="4">to generate loops, and also to test more heavily certain constructs</text>
<text top="1061" left="81" width="359" height="12" font="4">we suspected would reveal flaws in our implementation. For exam-</text>
<text top="1076" left="81" width="359" height="12" font="4">ple, we suspected bugs in TraceMonkey’s handling of type-unstable</text>
<text top="382" left="566" width="12" height="10" font="36">!&#34;#</text>
<text top="382" left="590" width="250" height="10" font="36">$!&#34;# %!&#34;# &amp;!&#34;# '!&#34;# (!&#34;# )!&#34;# *!&#34;# +!&#34;# ,!&#34;# $!!&#34;#</text>
<text top="365" left="525" width="40" height="8" font="37">&amp;-./012#3%4%56#</text>
<text top="355" left="520" width="45" height="8" font="37">&amp;-.789:;#3%4,56#</text>
<text top="345" left="516" width="49" height="8" font="37">&amp;-.9&lt;=&gt;9&lt;/2#3$4%56#</text>
<text top="335" left="496" width="70" height="8" font="37">&lt;//2??.1@A&lt;9=.&gt;922?#3!4,56#</text>
<text top="325" left="503" width="62" height="8" font="37">&lt;//2??.B&lt;AAC0/;#3%4%56#</text>
<text top="316" left="511" width="54" height="8" font="37">&lt;//2??.A18-=#3'4%56#</text>
<text top="306" left="511" width="54" height="8" font="37">&lt;//2??.A?@2D2#3&amp;4!56#</text>
<text top="296" left="482" width="83" height="8" font="37">1@&gt;8:?.&amp;1@&gt;.1@&gt;?.@A.1=&gt;2#3%(4(56#</text>
<text top="286" left="498" width="68" height="8" font="37">1@&gt;8:?.1@&gt;?.@A.1=&gt;2#3+4*56#</text>
<text top="276" left="494" width="72" height="8" font="37">1@&gt;8:?.1@&gt;E@?2.&lt;A-#3%(4%56#</text>
<text top="266" left="500" width="66" height="8" font="37">1@&gt;8:?.A?@2D2.1@&gt;?#3%4*56#</text>
<text top="256" left="490" width="75" height="8" font="37">/8A&gt;98FG8E.92/09?@D2#3$4!56#</text>
<text top="246" left="519" width="46" height="8" font="37">/9=:&gt;8.&lt;2?#3$4)56#</text>
<text top="236" left="516" width="50" height="8" font="37">/9=:&gt;8.7-(#3%4&amp;56#</text>
<text top="227" left="515" width="50" height="8" font="37">/9=:&gt;8.?;&lt;$#3(4,56#</text>
<text top="217" left="500" width="65" height="8" font="37">-&lt;&gt;2.B897&lt;&gt;.&gt;8H2#3$4$56#</text>
<text top="207" left="498" width="67" height="8" font="37">-&lt;&gt;2.B897&lt;&gt;.5:&lt;91#3$4!56#</text>
<text top="197" left="515" width="51" height="8" font="37">7&lt;&gt;;./89-@/#3'4,56#</text>
<text top="187" left="498" width="67" height="8" font="37">7&lt;&gt;;.:&lt;9I&lt;F.?07?#3(4,56#</text>
<text top="177" left="493" width="72" height="8" font="37">7&lt;&gt;;.?:2/&gt;9&lt;F.A897#3*4$56#</text>
<text top="167" left="517" width="48" height="8" font="37">92J25:.-A&lt;#3'4%56#</text>
<text top="157" left="511" width="55" height="8" font="37">?&gt;9@AJ.1&lt;?2)'#3%4(56#</text>
<text top="147" left="517" width="48" height="8" font="37">?&gt;9@AJ.B&lt;?&gt;&lt;#3$4(56#</text>
<text top="138" left="507" width="58" height="8" font="37">?&gt;9@AJ.&gt;&lt;J/F80-#3$4$56#</text>
<text top="128" left="496" width="69" height="8" font="37">?&gt;9@AJ.0A:&lt;/C./8-2#3$4%56#</text>
<text top="118" left="493" width="73" height="8" font="37">?&gt;9@AJ.D&lt;F@-&lt;&gt;2.@A:0&gt;#3$4,56#</text>
<text top="407" left="617" width="32" height="10" font="36">KA&gt;29:92&gt;#</text>
<text top="407" left="689" width="24" height="10" font="36">L&lt;ID2#</text>
<text top="452" left="476" width="359" height="12" font="15">Figure 11. Fraction of dynamic bytecodes executed by inter-</text>
<text top="467" left="476" width="158" height="12" font="15">preter and on native traces.</text>
<text top="467" left="637" width="197" height="12" font="4">The speedup vs. interpreter is shown</text>
<text top="482" left="476" width="359" height="12" font="4">in parentheses next to each test. The fraction of bytecodes exe-</text>
<text top="497" left="476" width="359" height="12" font="4">cuted while recording is too small to see in this figure, except</text>
<text top="512" left="476" width="16" height="12" font="4">for</text>
<text top="512" left="495" width="71" height="11" font="7">crypto-md5</text>
<text top="512" left="566" width="269" height="12" font="4">, where fully 3% of bytecodes are executed while</text>
<text top="527" left="476" width="359" height="12" font="4">recording. In most of the tests, almost all the bytecodes are exe-</text>
<text top="541" left="476" width="359" height="12" font="4">cuted by compiled traces. Three of the benchmarks are not traced</text>
<text top="556" left="476" width="166" height="12" font="4">at all and run in the interpreter.</text>
<text top="601" left="476" width="359" height="12" font="4">loops and heavily branching code, and a specialized fuzz tester in-</text>
<text top="616" left="476" width="359" height="12" font="4">deed revealed several regressions which we subsequently corrected.</text>
<text top="650" left="476" width="12" height="15" font="9">7.</text>
<text top="650" left="504" width="77" height="15" font="9">Evaluation</text>
<text top="673" left="476" width="359" height="12" font="4">We evaluated our JavaScript tracing implementation using Sun-</text>
<text top="688" left="476" width="359" height="12" font="4">Spider, the industry standard JavaScript benchmark suite. SunSpi-</text>
<text top="703" left="476" width="359" height="12" font="4">der consists of 26 short-running (less than 250ms, average 26ms)</text>
<text top="718" left="476" width="359" height="12" font="4">JavaScript programs. This is in stark contrast to benchmark suites</text>
<text top="733" left="476" width="359" height="12" font="4">such as SpecJVM98 (3) used to evaluate desktop and server Java</text>
<text top="747" left="476" width="359" height="12" font="4">VMs. Many programs in those benchmarks use large data sets and</text>
<text top="762" left="476" width="359" height="12" font="4">execute for minutes. The SunSpider programs carry out a variety of</text>
<text top="777" left="476" width="359" height="12" font="4">tasks, primarily 3d rendering, bit-bashing, cryptographic encoding,</text>
<text top="792" left="476" width="193" height="12" font="4">math kernels, and string processing.</text>
<text top="807" left="493" width="341" height="12" font="4">All experiments were performed on a MacBook Pro with 2.2</text>
<text top="822" left="476" width="329" height="12" font="4">GHz Core 2 processor and 2 GB RAM running MacOS 10.5.</text>
<text top="837" left="493" width="114" height="12" font="15">Benchmark results.</text>
<text top="837" left="612" width="222" height="12" font="4">The main question is whether programs</text>
<text top="852" left="476" width="359" height="12" font="4">run faster with tracing. For this, we ran the standard SunSpider test</text>
<text top="867" left="476" width="359" height="12" font="4">driver, which starts a JavaScript interpreter, loads and runs each</text>
<text top="882" left="476" width="359" height="12" font="4">program once for warmup, then loads and runs each program 10</text>
<text top="897" left="476" width="359" height="12" font="4">times and reports the average time taken by each. We ran 4 differ-</text>
<text top="912" left="476" width="359" height="12" font="4">ent configurations for comparison: (a) SpiderMonkey, the baseline</text>
<text top="927" left="476" width="359" height="12" font="4">interpreter, (b) TraceMonkey, (d) SquirrelFish Extreme (SFX), the</text>
<text top="942" left="476" width="359" height="12" font="4">call-threaded JavaScript interpreter used in Apple’s WebKit, and</text>
<text top="957" left="476" width="320" height="12" font="4">(e) V8, the method-compiling JavaScript VM from Google.</text>
<text top="972" left="493" width="341" height="12" font="4">Figure 10 shows the relative speedups achieved by tracing, SFX,</text>
<text top="987" left="476" width="359" height="12" font="4">and V8 against the baseline (SpiderMonkey). Tracing achieves the</text>
<text top="1001" left="476" width="359" height="12" font="4">best speedups in integer-heavy benchmarks, up to the 25x speedup</text>
<text top="1016" left="476" width="13" height="12" font="4">on</text>
<text top="1017" left="492" width="127" height="11" font="7">bitops-bitwise-and</text>
<text top="1016" left="619" width="3" height="12" font="4">.</text>
<text top="1031" left="493" width="341" height="12" font="4">TraceMonkey is the fastest VM on 9 of the 26 benchmarks</text>
<text top="1046" left="476" width="4" height="12" font="4">(</text>
<text top="1047" left="480" width="56" height="11" font="7">3d-morph</text>
<text top="1046" left="536" width="3" height="12" font="4">,</text>
<text top="1047" left="548" width="169" height="11" font="7">bitops-3bit-bits-in-byte</text>
<text top="1046" left="717" width="3" height="12" font="4">,</text>
<text top="1047" left="728" width="106" height="11" font="7">bitops-bitwise-</text>
<text top="1062" left="476" width="21" height="11" font="7">and</text>
<text top="1061" left="497" width="3" height="12" font="4">,</text>
<text top="1062" left="503" width="78" height="11" font="7">crypto-sha1</text>
<text top="1061" left="581" width="3" height="12" font="4">,</text>
<text top="1062" left="588" width="78" height="11" font="7">math-cordic</text>
<text top="1061" left="665" width="3" height="12" font="4">,</text>
<text top="1062" left="672" width="120" height="11" font="7">math-partial-sums</text>
<text top="1061" left="792" width="3" height="12" font="4">,</text>
<text top="1062" left="799" width="35" height="11" font="7">math-</text>
<text top="1077" left="476" width="92" height="11" font="7">spectral-norm</text>
<text top="1076" left="567" width="3" height="12" font="4">,</text>
<text top="1077" left="577" width="92" height="11" font="7">string-base64</text>
<text top="1076" left="669" width="3" height="12" font="4">,</text>
<text top="1077" left="678" width="148" height="11" font="7">string-validate-input</text>
<text top="1076" left="826" width="8" height="12" font="4">).</text>
</page>
<page number="11" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="38" size="15" family="JFNKJW+Calibri" color="#000000"/>
<text top="354" left="100" width="11" height="18" font="38">!&#34;</text>
<text top="305" left="100" width="11" height="18" font="38">#&#34;</text>
<text top="256" left="92" width="18" height="18" font="38">$!&#34;</text>
<text top="207" left="92" width="18" height="18" font="38">$#&#34;</text>
<text top="158" left="92" width="18" height="18" font="38">%!&#34;</text>
<text top="109" left="92" width="18" height="18" font="38">%#&#34;</text>
<text top="136" left="732" width="45" height="18" font="38">&amp;'()*+,&#34;</text>
<text top="162" left="732" width="24" height="18" font="38">-./&#34;</text>
<text top="188" left="732" width="19" height="18" font="38">01&#34;</text>
<text top="532" left="81" width="59" height="12" font="15">Figure 10.</text>
<text top="532" left="147" width="688" height="12" font="4">Speedup vs. a baseline JavaScript interpreter (SpiderMonkey) for our trace-based JIT compiler, Apple’s SquirrelFish Extreme</text>
<text top="547" left="81" width="753" height="12" font="4">inline threading interpreter and Google’s V8 JS compiler. Our system generates particularly efficient code for programs that benefit most from</text>
<text top="562" left="81" width="753" height="12" font="4">type specialization, which includes SunSpider Benchmark programs that perform bit manipulation. We type-specialize the code in question</text>
<text top="577" left="81" width="753" height="12" font="4">to use integer arithmetic, which substantially improves performance. For one of the benchmark programs we execute 25 times faster than</text>
<text top="592" left="81" width="753" height="12" font="4">the SpiderMonkey interpreter, and almost 5 times faster than V8 and SFX. For a large number of benchmarks all three VMs produce similar</text>
<text top="607" left="81" width="753" height="12" font="4">results. We perform worst on benchmark programs that we do not trace and instead fall back onto the interpreter. This includes the recursive</text>
<text top="622" left="81" width="65" height="12" font="4">benchmarks</text>
<text top="622" left="149" width="134" height="11" font="7">access-binary-trees</text>
<text top="622" left="287" width="19" height="12" font="4">and</text>
<text top="622" left="310" width="155" height="11" font="7">control-flow-recursive</text>
<text top="622" left="465" width="300" height="12" font="4">, for which we currently don’t generate any native code.</text>
<text top="666" left="81" width="89" height="12" font="4">In particular, the</text>
<text top="667" left="174" width="42" height="11" font="7">bitops</text>
<text top="666" left="220" width="219" height="12" font="4">benchmarks are short programs that per-</text>
<text top="681" left="81" width="359" height="12" font="4">form many bitwise operations, so TraceMonkey can cover the en-</text>
<text top="696" left="81" width="359" height="12" font="4">tire program with 1 or 2 traces that operate on integers. TraceMon-</text>
<text top="711" left="81" width="359" height="12" font="4">key runs all the other programs in this set almost entirely as native</text>
<text top="726" left="81" width="29" height="12" font="4">code.</text>
<text top="742" left="99" width="71" height="11" font="7">regexp-dna</text>
<text top="741" left="177" width="263" height="12" font="4">is dominated by regular expression matching,</text>
<text top="756" left="81" width="359" height="12" font="4">which is implemented in all 3 VMs by a special regular expression</text>
<text top="771" left="81" width="359" height="12" font="4">compiler. Thus, performance on this benchmark has little relation</text>
<text top="786" left="81" width="307" height="12" font="4">to the trace compilation approach discussed in this paper.</text>
<text top="801" left="99" width="341" height="12" font="4">TraceMonkey’s smaller speedups on the other benchmarks can</text>
<text top="816" left="81" width="200" height="12" font="4">be attributed to a few specific causes:</text>
<text top="854" left="89" width="6" height="11" font="2">•</text>
<text top="855" left="100" width="339" height="12" font="4">The implementation does not currently trace recursion, so</text>
<text top="870" left="100" width="339" height="12" font="4">TraceMonkey achieves a small speedup or no speedup on</text>
<text top="885" left="100" width="249" height="12" font="4">benchmarks that use recursion extensively:</text>
<text top="886" left="358" width="49" height="11" font="7">3d-cube</text>
<text top="885" left="407" width="3" height="12" font="4">,</text>
<text top="886" left="418" width="21" height="11" font="7">3d-</text>
<text top="901" left="100" width="56" height="11" font="7">raytrace</text>
<text top="900" left="157" width="3" height="12" font="4">,</text>
<text top="901" left="165" width="134" height="11" font="7">access-binary-trees</text>
<text top="900" left="299" width="3" height="12" font="4">,</text>
<text top="901" left="307" width="106" height="11" font="7">string-tagcloud</text>
<text top="900" left="412" width="27" height="12" font="4">, and</text>
<text top="916" left="100" width="148" height="11" font="7">controlflow-recursive</text>
<text top="915" left="249" width="3" height="12" font="4">.</text>
<text top="935" left="89" width="6" height="11" font="2">•</text>
<text top="936" left="100" width="248" height="12" font="4">The implementation does not currently trace</text>
<text top="937" left="353" width="28" height="11" font="7">eval</text>
<text top="936" left="387" width="53" height="12" font="4">and some</text>
<text top="951" left="100" width="248" height="12" font="4">other functions implemented in C. Because</text>
<text top="952" left="355" width="85" height="11" font="7">date-format-</text>
<text top="967" left="100" width="35" height="11" font="7">tofte</text>
<text top="966" left="141" width="19" height="12" font="4">and</text>
<text top="967" left="166" width="120" height="11" font="7">date-format-xparb</text>
<text top="966" left="291" width="149" height="12" font="4">use such functions in their</text>
<text top="981" left="100" width="182" height="12" font="4">main loops, we do not trace them.</text>
<text top="1000" left="89" width="6" height="11" font="2">•</text>
<text top="1001" left="100" width="339" height="12" font="4">The implementation does not currently trace through regular</text>
<text top="1016" left="100" width="57" height="12" font="4">expression</text>
<text top="1017" left="163" width="49" height="11" font="7">replace</text>
<text top="1016" left="218" width="222" height="12" font="4">operations. The replace function can be</text>
<text top="1031" left="100" width="339" height="12" font="4">passed a function object used to compute the replacement text.</text>
<text top="1046" left="100" width="339" height="12" font="4">Our implementation currently does not trace functions called</text>
<text top="1061" left="100" width="197" height="12" font="4">as replace functions. The run time of</text>
<text top="1062" left="300" width="127" height="11" font="7">string-unpack-code</text>
<text top="1061" left="431" width="9" height="12" font="4">is</text>
<text top="1076" left="100" width="111" height="12" font="4">dominated by such a</text>
<text top="1077" left="215" width="49" height="11" font="7">replace</text>
<text top="1076" left="268" width="23" height="12" font="4">call.</text>
<text top="665" left="483" width="6" height="11" font="2">•</text>
<text top="666" left="495" width="339" height="12" font="4">Two programs trace well, but have a long compilation time.</text>
<text top="682" left="495" width="85" height="11" font="7">access-nbody</text>
<text top="681" left="582" width="189" height="12" font="4">forms a large number of traces (81).</text>
<text top="682" left="774" width="71" height="11" font="7">crypto-md5</text>
<text top="696" left="495" width="339" height="12" font="4">forms one very long trace. We expect to improve performance</text>
<text top="711" left="495" width="339" height="12" font="4">on this programs by improving the compilation speed of nano-</text>
<text top="726" left="495" width="15" height="12" font="4">jit.</text>
<text top="746" left="483" width="6" height="11" font="2">•</text>
<text top="747" left="495" width="339" height="12" font="4">Some programs trace very well, and speed up compared to</text>
<text top="762" left="495" width="339" height="12" font="4">the interpreter, but are not as fast as SFX and/or V8, namely</text>
<text top="778" left="495" width="134" height="11" font="7">bitops-bits-in-byte</text>
<text top="777" left="629" width="3" height="12" font="4">,</text>
<text top="778" left="643" width="127" height="11" font="7">bitops-nsieve-bits</text>
<text top="777" left="770" width="3" height="12" font="4">,</text>
<text top="778" left="785" width="49" height="11" font="7">access-</text>
<text top="793" left="495" width="56" height="11" font="7">fannkuch</text>
<text top="792" left="551" width="3" height="12" font="4">,</text>
<text top="793" left="559" width="92" height="11" font="7">access-nsieve</text>
<text top="792" left="651" width="27" height="12" font="4">, and</text>
<text top="793" left="682" width="71" height="11" font="7">crypto-aes</text>
<text top="792" left="753" width="81" height="12" font="4">. The reason is</text>
<text top="807" left="495" width="339" height="12" font="4">not clear, but all of these programs have nested loops with</text>
<text top="822" left="495" width="339" height="12" font="4">small bodies, so we suspect that the implementation has a rela-</text>
<text top="837" left="495" width="217" height="12" font="4">tively high cost for calling nested traces.</text>
<text top="838" left="715" width="85" height="11" font="7">string-fasta</text>
<text top="837" left="803" width="31" height="12" font="4">traces</text>
<text top="852" left="495" width="339" height="12" font="4">well, but its run time is dominated by string processing builtins,</text>
<text top="867" left="495" width="339" height="12" font="4">which are unaffected by tracing and seem to be less efficient in</text>
<text top="882" left="495" width="228" height="12" font="4">SpiderMonkey than in the two other VMs.</text>
<text top="912" left="493" width="174" height="12" font="15">Detailed performance metrics.</text>
<text top="912" left="670" width="164" height="12" font="4">In Figure 11 we show the frac-</text>
<text top="927" left="476" width="359" height="12" font="4">tion of instructions interpreted and the fraction of instructions exe-</text>
<text top="942" left="476" width="359" height="12" font="4">cuted as native code. This figure shows that for many programs, we</text>
<text top="957" left="476" width="253" height="12" font="4">are able to execute almost all the code natively.</text>
<text top="972" left="493" width="341" height="12" font="4">Figure 12 breaks down the total execution time into four activ-</text>
<text top="987" left="476" width="359" height="12" font="4">ities: interpreting bytecodes while not recording, recording traces</text>
<text top="1001" left="476" width="359" height="12" font="4">(including time taken to interpret the recorded trace), compiling</text>
<text top="1016" left="476" width="294" height="12" font="4">traces to native code, and executing native code traces.</text>
<text top="1031" left="493" width="341" height="12" font="4">These detailed metrics allow us to estimate parameters for a</text>
<text top="1046" left="476" width="359" height="12" font="4">simple model of tracing performance. These estimates should be</text>
<text top="1061" left="476" width="359" height="12" font="4">considered very rough, as the values observed on the individual</text>
<text top="1076" left="476" width="359" height="12" font="4">benchmarks have large standard deviations (on the order of the</text>
</page>
<page number="12" position="absolute" top="0" left="0" height="1188" width="918">
<text top="109" left="250" width="34" height="12" font="4">Loops</text>
<text top="109" left="301" width="29" height="12" font="4">Trees</text>
<text top="109" left="349" width="35" height="12" font="4">Traces</text>
<text top="109" left="402" width="37" height="12" font="4">Aborts</text>
<text top="109" left="457" width="41" height="12" font="4">Flushes</text>
<text top="109" left="516" width="62" height="12" font="4">Trees/Loop</text>
<text top="109" left="595" width="63" height="12" font="4">Traces/Tree</text>
<text top="109" left="676" width="68" height="12" font="4">Traces/Loop</text>
<text top="109" left="762" width="46" height="12" font="4">Speedup</text>
<text top="125" left="107" width="43" height="12" font="4">3d-cube</text>
<text top="125" left="270" width="13" height="12" font="4">25</text>
<text top="125" left="317" width="13" height="12" font="4">27</text>
<text top="125" left="371" width="13" height="12" font="4">29</text>
<text top="125" left="432" width="7" height="12" font="4">3</text>
<text top="125" left="491" width="7" height="12" font="4">0</text>
<text top="125" left="560" width="17" height="12" font="4">1.1</text>
<text top="125" left="642" width="17" height="12" font="4">1.1</text>
<text top="125" left="727" width="17" height="12" font="4">1.2</text>
<text top="125" left="778" width="30" height="12" font="4">2.20x</text>
<text top="140" left="107" width="53" height="12" font="4">3d-morph</text>
<text top="140" left="277" width="7" height="12" font="4">5</text>
<text top="140" left="324" width="7" height="12" font="4">8</text>
<text top="140" left="377" width="7" height="12" font="4">8</text>
<text top="140" left="432" width="7" height="12" font="4">2</text>
<text top="140" left="491" width="7" height="12" font="4">0</text>
<text top="140" left="560" width="17" height="12" font="4">1.6</text>
<text top="140" left="642" width="17" height="12" font="4">1.0</text>
<text top="140" left="727" width="17" height="12" font="4">1.6</text>
<text top="140" left="778" width="30" height="12" font="4">2.86x</text>
<text top="155" left="107" width="61" height="12" font="4">3d-raytrace</text>
<text top="155" left="270" width="13" height="12" font="4">10</text>
<text top="155" left="317" width="13" height="12" font="4">25</text>
<text top="155" left="364" width="20" height="12" font="4">100</text>
<text top="155" left="425" width="13" height="12" font="4">10</text>
<text top="155" left="491" width="7" height="12" font="4">1</text>
<text top="155" left="560" width="17" height="12" font="4">2.5</text>
<text top="155" left="642" width="17" height="12" font="4">4.0</text>
<text top="155" left="720" width="24" height="12" font="4">10.0</text>
<text top="155" left="778" width="30" height="12" font="4">1.18x</text>
<text top="170" left="107" width="103" height="12" font="4">access-binary-trees</text>
<text top="170" left="277" width="7" height="12" font="4">0</text>
<text top="170" left="324" width="7" height="12" font="4">0</text>
<text top="170" left="377" width="7" height="12" font="4">0</text>
<text top="170" left="432" width="7" height="12" font="4">5</text>
<text top="170" left="491" width="7" height="12" font="4">0</text>
<text top="170" left="573" width="4" height="12" font="4">-</text>
<text top="170" left="654" width="4" height="12" font="4">-</text>
<text top="170" left="739" width="4" height="12" font="4">-</text>
<text top="170" left="778" width="30" height="12" font="4">0.93x</text>
<text top="185" left="107" width="89" height="12" font="4">access-fannkuch</text>
<text top="185" left="270" width="13" height="12" font="4">10</text>
<text top="185" left="317" width="13" height="12" font="4">34</text>
<text top="185" left="371" width="13" height="12" font="4">57</text>
<text top="185" left="425" width="13" height="12" font="4">24</text>
<text top="185" left="491" width="7" height="12" font="4">0</text>
<text top="185" left="560" width="17" height="12" font="4">3.4</text>
<text top="185" left="642" width="17" height="12" font="4">1.7</text>
<text top="185" left="727" width="17" height="12" font="4">5.7</text>
<text top="185" left="778" width="30" height="12" font="4">2.20x</text>
<text top="200" left="107" width="72" height="12" font="4">access-nbody</text>
<text top="200" left="277" width="7" height="12" font="4">8</text>
<text top="200" left="317" width="13" height="12" font="4">16</text>
<text top="200" left="371" width="13" height="12" font="4">18</text>
<text top="200" left="432" width="7" height="12" font="4">5</text>
<text top="200" left="491" width="7" height="12" font="4">0</text>
<text top="200" left="560" width="17" height="12" font="4">2.0</text>
<text top="200" left="642" width="17" height="12" font="4">1.1</text>
<text top="200" left="727" width="17" height="12" font="4">2.3</text>
<text top="200" left="778" width="30" height="12" font="4">4.19x</text>
<text top="215" left="107" width="73" height="12" font="4">access-nsieve</text>
<text top="215" left="277" width="7" height="12" font="4">3</text>
<text top="215" left="324" width="7" height="12" font="4">6</text>
<text top="215" left="377" width="7" height="12" font="4">8</text>
<text top="215" left="432" width="7" height="12" font="4">3</text>
<text top="215" left="491" width="7" height="12" font="4">0</text>
<text top="215" left="560" width="17" height="12" font="4">2.0</text>
<text top="215" left="642" width="17" height="12" font="4">1.3</text>
<text top="215" left="727" width="17" height="12" font="4">2.7</text>
<text top="215" left="778" width="30" height="12" font="4">3.05x</text>
<text top="229" left="107" width="125" height="12" font="4">bitops-3bit-bits-in-byte</text>
<text top="229" left="277" width="7" height="12" font="4">2</text>
<text top="229" left="324" width="7" height="12" font="4">2</text>
<text top="229" left="377" width="7" height="12" font="4">2</text>
<text top="229" left="432" width="7" height="12" font="4">0</text>
<text top="229" left="491" width="7" height="12" font="4">0</text>
<text top="229" left="560" width="17" height="12" font="4">1.0</text>
<text top="229" left="642" width="17" height="12" font="4">1.0</text>
<text top="229" left="727" width="17" height="12" font="4">1.0</text>
<text top="229" left="771" width="37" height="12" font="4">25.47x</text>
<text top="244" left="107" width="99" height="12" font="4">bitops-bits-in-byte</text>
<text top="244" left="277" width="7" height="12" font="4">3</text>
<text top="244" left="324" width="7" height="12" font="4">3</text>
<text top="244" left="377" width="7" height="12" font="4">4</text>
<text top="244" left="432" width="7" height="12" font="4">1</text>
<text top="244" left="491" width="7" height="12" font="4">0</text>
<text top="244" left="560" width="17" height="12" font="4">1.0</text>
<text top="244" left="642" width="17" height="12" font="4">1.3</text>
<text top="244" left="727" width="17" height="12" font="4">1.3</text>
<text top="244" left="778" width="30" height="12" font="4">8.67x</text>
<text top="259" left="107" width="100" height="12" font="4">bitops-bitwise-and</text>
<text top="259" left="277" width="7" height="12" font="4">1</text>
<text top="259" left="324" width="7" height="12" font="4">1</text>
<text top="259" left="377" width="7" height="12" font="4">1</text>
<text top="259" left="432" width="7" height="12" font="4">0</text>
<text top="259" left="491" width="7" height="12" font="4">0</text>
<text top="259" left="560" width="17" height="12" font="4">1.0</text>
<text top="259" left="642" width="17" height="12" font="4">1.0</text>
<text top="259" left="727" width="17" height="12" font="4">1.0</text>
<text top="259" left="771" width="37" height="12" font="4">25.20x</text>
<text top="274" left="107" width="95" height="12" font="4">bitops-nsieve-bits</text>
<text top="274" left="277" width="7" height="12" font="4">3</text>
<text top="274" left="324" width="7" height="12" font="4">3</text>
<text top="274" left="377" width="7" height="12" font="4">5</text>
<text top="274" left="432" width="7" height="12" font="4">0</text>
<text top="274" left="491" width="7" height="12" font="4">0</text>
<text top="274" left="560" width="17" height="12" font="4">1.0</text>
<text top="274" left="642" width="17" height="12" font="4">1.7</text>
<text top="274" left="727" width="17" height="12" font="4">1.7</text>
<text top="274" left="778" width="30" height="12" font="4">2.75x</text>
<text top="289" left="107" width="115" height="12" font="4">controlflow-recursive</text>
<text top="289" left="277" width="7" height="12" font="4">0</text>
<text top="289" left="324" width="7" height="12" font="4">0</text>
<text top="289" left="377" width="7" height="12" font="4">0</text>
<text top="289" left="432" width="7" height="12" font="4">1</text>
<text top="289" left="491" width="7" height="12" font="4">0</text>
<text top="289" left="573" width="4" height="12" font="4">-</text>
<text top="289" left="654" width="4" height="12" font="4">-</text>
<text top="289" left="739" width="4" height="12" font="4">-</text>
<text top="289" left="778" width="30" height="12" font="4">0.98x</text>
<text top="304" left="107" width="56" height="12" font="4">crypto-aes</text>
<text top="304" left="270" width="13" height="12" font="4">50</text>
<text top="304" left="317" width="13" height="12" font="4">72</text>
<text top="304" left="371" width="13" height="12" font="4">78</text>
<text top="304" left="425" width="13" height="12" font="4">19</text>
<text top="304" left="491" width="7" height="12" font="4">0</text>
<text top="304" left="560" width="17" height="12" font="4">1.4</text>
<text top="304" left="642" width="17" height="12" font="4">1.1</text>
<text top="304" left="727" width="17" height="12" font="4">1.6</text>
<text top="304" left="778" width="30" height="12" font="4">1.64x</text>
<text top="319" left="107" width="63" height="12" font="4">crypto-md5</text>
<text top="319" left="277" width="7" height="12" font="4">4</text>
<text top="319" left="324" width="7" height="12" font="4">4</text>
<text top="319" left="377" width="7" height="12" font="4">5</text>
<text top="319" left="432" width="7" height="12" font="4">0</text>
<text top="319" left="491" width="7" height="12" font="4">0</text>
<text top="319" left="560" width="17" height="12" font="4">1.0</text>
<text top="319" left="642" width="17" height="12" font="4">1.3</text>
<text top="319" left="727" width="17" height="12" font="4">1.3</text>
<text top="319" left="778" width="30" height="12" font="4">2.30x</text>
<text top="334" left="107" width="63" height="12" font="4">crypto-sha1</text>
<text top="334" left="277" width="7" height="12" font="4">5</text>
<text top="334" left="324" width="7" height="12" font="4">5</text>
<text top="334" left="371" width="13" height="12" font="4">10</text>
<text top="334" left="432" width="7" height="12" font="4">0</text>
<text top="334" left="491" width="7" height="12" font="4">0</text>
<text top="334" left="560" width="17" height="12" font="4">1.0</text>
<text top="334" left="642" width="17" height="12" font="4">2.0</text>
<text top="334" left="727" width="17" height="12" font="4">2.0</text>
<text top="334" left="778" width="30" height="12" font="4">5.95x</text>
<text top="349" left="107" width="92" height="12" font="4">date-format-tofte</text>
<text top="349" left="277" width="7" height="12" font="4">3</text>
<text top="349" left="324" width="7" height="12" font="4">3</text>
<text top="349" left="377" width="7" height="12" font="4">4</text>
<text top="349" left="432" width="7" height="12" font="4">7</text>
<text top="349" left="491" width="7" height="12" font="4">0</text>
<text top="349" left="560" width="17" height="12" font="4">1.0</text>
<text top="349" left="642" width="17" height="12" font="4">1.3</text>
<text top="349" left="727" width="17" height="12" font="4">1.3</text>
<text top="349" left="778" width="30" height="12" font="4">1.07x</text>
<text top="364" left="107" width="98" height="12" font="4">date-format-xparb</text>
<text top="364" left="277" width="7" height="12" font="4">3</text>
<text top="364" left="324" width="7" height="12" font="4">3</text>
<text top="364" left="371" width="13" height="12" font="4">11</text>
<text top="364" left="432" width="7" height="12" font="4">3</text>
<text top="364" left="491" width="7" height="12" font="4">0</text>
<text top="364" left="560" width="17" height="12" font="4">1.0</text>
<text top="364" left="642" width="17" height="12" font="4">3.7</text>
<text top="364" left="727" width="17" height="12" font="4">3.7</text>
<text top="364" left="778" width="30" height="12" font="4">0.98x</text>
<text top="379" left="107" width="65" height="12" font="4">math-cordic</text>
<text top="379" left="277" width="7" height="12" font="4">2</text>
<text top="379" left="324" width="7" height="12" font="4">4</text>
<text top="379" left="377" width="7" height="12" font="4">5</text>
<text top="379" left="432" width="7" height="12" font="4">1</text>
<text top="379" left="491" width="7" height="12" font="4">0</text>
<text top="379" left="560" width="17" height="12" font="4">2.0</text>
<text top="379" left="642" width="17" height="12" font="4">1.3</text>
<text top="379" left="727" width="17" height="12" font="4">2.5</text>
<text top="379" left="778" width="30" height="12" font="4">4.92x</text>
<text top="394" left="107" width="98" height="12" font="4">math-partial-sums</text>
<text top="394" left="277" width="7" height="12" font="4">2</text>
<text top="394" left="324" width="7" height="12" font="4">4</text>
<text top="394" left="377" width="7" height="12" font="4">4</text>
<text top="394" left="432" width="7" height="12" font="4">1</text>
<text top="394" left="491" width="7" height="12" font="4">0</text>
<text top="394" left="560" width="17" height="12" font="4">2.0</text>
<text top="394" left="642" width="17" height="12" font="4">1.0</text>
<text top="394" left="727" width="17" height="12" font="4">2.0</text>
<text top="394" left="778" width="30" height="12" font="4">5.90x</text>
<text top="409" left="107" width="106" height="12" font="4">math-spectral-norm</text>
<text top="409" left="270" width="13" height="12" font="4">15</text>
<text top="409" left="317" width="13" height="12" font="4">20</text>
<text top="409" left="371" width="13" height="12" font="4">20</text>
<text top="409" left="432" width="7" height="12" font="4">0</text>
<text top="409" left="491" width="7" height="12" font="4">0</text>
<text top="409" left="560" width="17" height="12" font="4">1.3</text>
<text top="409" left="642" width="17" height="12" font="4">1.0</text>
<text top="409" left="727" width="17" height="12" font="4">1.3</text>
<text top="409" left="778" width="30" height="12" font="4">7.12x</text>
<text top="424" left="107" width="60" height="12" font="4">regexp-dna</text>
<text top="424" left="277" width="7" height="12" font="4">2</text>
<text top="424" left="324" width="7" height="12" font="4">2</text>
<text top="424" left="377" width="7" height="12" font="4">2</text>
<text top="424" left="432" width="7" height="12" font="4">0</text>
<text top="424" left="491" width="7" height="12" font="4">0</text>
<text top="424" left="560" width="17" height="12" font="4">1.0</text>
<text top="424" left="642" width="17" height="12" font="4">1.0</text>
<text top="424" left="727" width="17" height="12" font="4">1.0</text>
<text top="424" left="778" width="30" height="12" font="4">4.21x</text>
<text top="439" left="107" width="72" height="12" font="4">string-base64</text>
<text top="439" left="277" width="7" height="12" font="4">3</text>
<text top="439" left="324" width="7" height="12" font="4">5</text>
<text top="439" left="377" width="7" height="12" font="4">7</text>
<text top="439" left="432" width="7" height="12" font="4">0</text>
<text top="439" left="491" width="7" height="12" font="4">0</text>
<text top="439" left="560" width="17" height="12" font="4">1.7</text>
<text top="439" left="642" width="17" height="12" font="4">1.4</text>
<text top="439" left="727" width="17" height="12" font="4">2.3</text>
<text top="439" left="778" width="30" height="12" font="4">2.53x</text>
<text top="454" left="107" width="60" height="12" font="4">string-fasta</text>
<text top="454" left="277" width="7" height="12" font="4">5</text>
<text top="454" left="317" width="13" height="12" font="4">11</text>
<text top="454" left="371" width="13" height="12" font="4">15</text>
<text top="454" left="432" width="7" height="12" font="4">6</text>
<text top="454" left="491" width="7" height="12" font="4">0</text>
<text top="454" left="560" width="17" height="12" font="4">2.2</text>
<text top="454" left="642" width="17" height="12" font="4">1.4</text>
<text top="454" left="727" width="17" height="12" font="4">3.0</text>
<text top="454" left="778" width="30" height="12" font="4">1.49x</text>
<text top="469" left="107" width="81" height="12" font="4">string-tagcloud</text>
<text top="469" left="277" width="7" height="12" font="4">3</text>
<text top="469" left="324" width="7" height="12" font="4">6</text>
<text top="469" left="377" width="7" height="12" font="4">6</text>
<text top="469" left="432" width="7" height="12" font="4">5</text>
<text top="469" left="491" width="7" height="12" font="4">0</text>
<text top="469" left="560" width="17" height="12" font="4">2.0</text>
<text top="469" left="642" width="17" height="12" font="4">1.0</text>
<text top="469" left="727" width="17" height="12" font="4">2.0</text>
<text top="469" left="778" width="30" height="12" font="4">1.09x</text>
<text top="484" left="107" width="104" height="12" font="4">string-unpack-code</text>
<text top="484" left="277" width="7" height="12" font="4">4</text>
<text top="484" left="324" width="7" height="12" font="4">4</text>
<text top="484" left="371" width="13" height="12" font="4">37</text>
<text top="484" left="432" width="7" height="12" font="4">0</text>
<text top="484" left="491" width="7" height="12" font="4">0</text>
<text top="484" left="560" width="17" height="12" font="4">1.0</text>
<text top="484" left="642" width="17" height="12" font="4">9.3</text>
<text top="484" left="727" width="17" height="12" font="4">9.3</text>
<text top="484" left="778" width="30" height="12" font="4">1.20x</text>
<text top="498" left="107" width="109" height="12" font="4">string-validate-input</text>
<text top="498" left="277" width="7" height="12" font="4">6</text>
<text top="498" left="317" width="13" height="12" font="4">10</text>
<text top="498" left="371" width="13" height="12" font="4">13</text>
<text top="498" left="432" width="7" height="12" font="4">1</text>
<text top="498" left="491" width="7" height="12" font="4">0</text>
<text top="498" left="560" width="17" height="12" font="4">1.7</text>
<text top="498" left="642" width="17" height="12" font="4">1.3</text>
<text top="498" left="727" width="17" height="12" font="4">2.2</text>
<text top="498" left="778" width="30" height="12" font="4">1.86x</text>
<text top="535" left="242" width="58" height="12" font="15">Figure 13.</text>
<text top="535" left="307" width="363" height="12" font="4">Detailed trace recording statistics for the SunSpider benchmark set.</text>
<text top="580" left="81" width="105" height="12" font="4">mean). We exclude</text>
<text top="581" left="190" width="71" height="11" font="7">regexp-dna</text>
<text top="580" left="265" width="175" height="12" font="4">from the following calculations,</text>
<text top="595" left="81" width="359" height="12" font="4">because most of its time is spent in the regular expression matcher,</text>
<text top="610" left="81" width="359" height="12" font="4">which has much different performance characteristics from the</text>
<text top="625" left="81" width="359" height="12" font="4">other programs. (Note that this only makes a difference of about</text>
<text top="640" left="81" width="359" height="12" font="4">10% in the results.) Dividing the total execution time in processor</text>
<text top="655" left="81" width="359" height="12" font="4">clock cycles by the number of bytecodes executed in the base</text>
<text top="670" left="81" width="359" height="12" font="4">interpreter shows that on average, a bytecode executes in about</text>
<text top="685" left="81" width="359" height="12" font="4">35 cycles. Native traces take about 9 cycles per bytecode, a 3.9x</text>
<text top="699" left="81" width="153" height="12" font="4">speedup over the interpreter.</text>
<text top="714" left="99" width="341" height="12" font="4">Using similar computations, we find that trace recording takes</text>
<text top="729" left="81" width="359" height="12" font="4">about 3800 cycles per bytecode, and compilation 3150 cycles per</text>
<text top="744" left="81" width="359" height="12" font="4">bytecode. Hence, during recording and compiling the VM runs at</text>
<text top="759" left="81" width="359" height="12" font="4">1/200 the speed of the interpreter. Because it costs 6950 cycles to</text>
<text top="774" left="81" width="359" height="12" font="4">compile a bytecode, and we save 26 cycles each time that code is</text>
<text top="789" left="81" width="319" height="12" font="4">run natively, we break even after running a trace 270 times.</text>
<text top="804" left="99" width="341" height="12" font="4">The other VMs we compared with achieve an overall speedup</text>
<text top="819" left="81" width="359" height="12" font="4">of 3.0x relative to our baseline interpreter. Our estimated native</text>
<text top="834" left="81" width="359" height="12" font="4">code speedup of 3.9x is significantly better. This suggests that</text>
<text top="849" left="81" width="359" height="12" font="4">our compilation techniques can generate more efficient native code</text>
<text top="864" left="81" width="205" height="12" font="4">than any other current JavaScript VM.</text>
<text top="879" left="99" width="341" height="12" font="4">These estimates also indicate that our startup performance could</text>
<text top="894" left="81" width="359" height="12" font="4">be substantially better if we improved the speed of trace recording</text>
<text top="909" left="81" width="359" height="12" font="4">and compilation. The estimated 200x slowdown for recording and</text>
<text top="924" left="81" width="359" height="12" font="4">compilation is very rough, and may be influenced by startup factors</text>
<text top="939" left="81" width="359" height="12" font="4">in the interpreter (e.g., caches that have not warmed up yet during</text>
<text top="953" left="81" width="359" height="12" font="4">recording). One observation supporting this conjecture is that in</text>
<text top="968" left="81" width="359" height="12" font="4">the tracer, interpreted bytecodes take about 180 cycles to run. Still,</text>
<text top="983" left="81" width="359" height="12" font="4">recording and compilation are clearly both expensive, and a better</text>
<text top="998" left="81" width="359" height="12" font="4">implementation, possibly including redesign of the LIR abstract</text>
<text top="1013" left="81" width="305" height="12" font="4">syntax or encoding, would improve startup performance.</text>
<text top="1028" left="99" width="341" height="12" font="4">Our performance results confirm that type specialization using</text>
<text top="1043" left="81" width="359" height="12" font="4">trace trees substantially improves performance. We are able to</text>
<text top="1058" left="81" width="359" height="12" font="4">outperform the fastest available JavaScript compiler (V8) and the</text>
<text top="580" left="476" width="359" height="12" font="4">fastest available JavaScript inline threaded interpreter (SFX) on 9</text>
<text top="595" left="476" width="100" height="12" font="4">of 26 benchmarks.</text>
<text top="650" left="476" width="12" height="15" font="9">8.</text>
<text top="650" left="504" width="98" height="15" font="9">Related Work</text>
<text top="673" left="476" width="249" height="12" font="15">Trace optimization for dynamic languages.</text>
<text top="673" left="730" width="105" height="12" font="4">The closest area of</text>
<text top="688" left="476" width="359" height="12" font="4">related work is on applying trace optimization to type-specialize</text>
<text top="703" left="476" width="359" height="12" font="4">dynamic languages. Existing work shares the idea of generating</text>
<text top="718" left="476" width="359" height="12" font="4">type-specialized code speculatively with guards along interpreter</text>
<text top="733" left="476" width="35" height="12" font="4">traces.</text>
<text top="747" left="493" width="341" height="12" font="4">To our knowledge, Rigo’s Psyco (16) is the only published</text>
<text top="762" left="476" width="359" height="12" font="4">type-specializing trace compiler for a dynamic language (Python).</text>
<text top="777" left="476" width="359" height="12" font="4">Psyco does not attempt to identify hot loops or inline function calls.</text>
<text top="792" left="476" width="359" height="12" font="4">Instead, Psyco transforms loops to mutual recursion before running</text>
<text top="807" left="476" width="134" height="12" font="4">and traces all operations.</text>
<text top="822" left="493" width="341" height="12" font="4">Pall’s LuaJIT is a Lua VM in development that uses trace com-</text>
<text top="837" left="476" width="359" height="12" font="4">pilation ideas. (1). There are no publications on LuaJIT but the cre-</text>
<text top="852" left="476" width="359" height="12" font="4">ator has told us that LuaJIT has a similar design to our system, but</text>
<text top="867" left="476" width="359" height="12" font="4">will use a less aggressive type speculation (e.g., using a floating-</text>
<text top="882" left="476" width="359" height="12" font="4">point representation for all number values) and does not generate</text>
<text top="897" left="476" width="162" height="12" font="4">nested traces for nested loops.</text>
<text top="912" left="493" width="163" height="12" font="15">General trace optimization.</text>
<text top="912" left="662" width="172" height="12" font="4">General trace optimization has</text>
<text top="927" left="476" width="359" height="12" font="4">a longer history that has treated mostly native code and typed</text>
<text top="942" left="476" width="359" height="12" font="4">languages like Java. Thus, these systems have focused less on type</text>
<text top="957" left="476" width="256" height="12" font="4">specialization and more on other optimizations.</text>
<text top="972" left="493" width="341" height="12" font="4">Dynamo (7) by Bala et al, introduced native code tracing as a</text>
<text top="987" left="476" width="359" height="12" font="4">replacement for profile-guided optimization (PGO). A major goal</text>
<text top="1001" left="476" width="359" height="12" font="4">was to perform PGO online so that the profile was specific to</text>
<text top="1016" left="476" width="359" height="12" font="4">the current execution. Dynamo used loop headers as candidate hot</text>
<text top="1031" left="476" width="293" height="12" font="4">traces, but did not try to create loop traces specifically.</text>
<text top="1046" left="493" width="341" height="12" font="4">Trace trees were originally proposed by Gal et al. (11) in the</text>
<text top="1061" left="476" width="359" height="12" font="4">context of Java, a statically typed language. Their trace trees ac-</text>
<text top="1076" left="476" width="359" height="12" font="4">tually inlined parts of outer loops within the inner loops (because</text>
</page>
<page number="13" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="39" size="8" family="BFRJLG+Calibri" color="#000000"/>
	<fontspec id="40" size="7" family="BFRJLG+Calibri" color="#000000"/>
<text top="382" left="173" width="12" height="10" font="39">!&#34;#</text>
<text top="382" left="222" width="16" height="10" font="39">$!&#34;#</text>
<text top="382" left="273" width="16" height="10" font="39">%!&#34;#</text>
<text top="382" left="324" width="16" height="10" font="39">&amp;!&#34;#</text>
<text top="382" left="375" width="16" height="10" font="39">'!&#34;#</text>
<text top="382" left="424" width="20" height="10" font="39">(!!&#34;#</text>
<text top="365" left="133" width="40" height="8" font="40">)*+,-./#0$1$23#</text>
<text top="355" left="128" width="45" height="8" font="40">)*+45678#0$1923#</text>
<text top="345" left="124" width="49" height="8" font="40">)*+6:;&lt;6:,/#0(1$23#</text>
<text top="336" left="103" width="70" height="8" font="40">:,,/==+.&gt;?:6;+&lt;6//=#0!1923#</text>
<text top="326" left="111" width="62" height="8" font="40">:,,/==+@:??A-,8#0$1$23#</text>
<text top="316" left="118" width="54" height="8" font="40">:,,/==+?.5*;#0%1$23#</text>
<text top="306" left="118" width="54" height="8" font="40">:,,/==+?=&gt;/B/#0)1!23#</text>
<text top="296" left="89" width="83" height="8" font="40">.&gt;&lt;57=+).&gt;&lt;+.&gt;&lt;=+&gt;?+.;&lt;/#0$C1C23#</text>
<text top="286" left="105" width="68" height="8" font="40">.&gt;&lt;57=+.&gt;&lt;=+&gt;?+.;&lt;/#0'1D23#</text>
<text top="277" left="101" width="72" height="8" font="40">.&gt;&lt;57=+.&gt;&lt;E&gt;=/+:?*#0$C1$23#</text>
<text top="267" left="107" width="66" height="8" font="40">.&gt;&lt;57=+?=&gt;/B/+.&gt;&lt;=#0$1D23#</text>
<text top="257" left="98" width="75" height="8" font="40">,5?&lt;65FG5E+6/,-6=&gt;B/#0(1!23#</text>
<text top="247" left="126" width="46" height="8" font="40">,6;7&lt;5+:/=#0(1&amp;23#</text>
<text top="237" left="123" width="50" height="8" font="40">,6;7&lt;5+4*C#0$1)23#</text>
<text top="228" left="123" width="50" height="8" font="40">,6;7&lt;5+=8:(#0C1923#</text>
<text top="218" left="107" width="65" height="8" font="40">*:&lt;/+@564:&lt;+&lt;5H/#0(1(23#</text>
<text top="208" left="105" width="67" height="8" font="40">*:&lt;/+@564:&lt;+27:6.#0(1!23#</text>
<text top="198" left="122" width="51" height="8" font="40">4:&lt;8+,56*&gt;,#0%1923#</text>
<text top="188" left="105" width="67" height="8" font="40">4:&lt;8+7:6I:F+=-4=#0C1923#</text>
<text top="178" left="101" width="72" height="8" font="40">4:&lt;8+=7/,&lt;6:F+?564#0D1(23#</text>
<text top="169" left="124" width="48" height="8" font="40">6/J/27+*?:#0%1$23#</text>
<text top="159" left="118" width="55" height="8" font="40">=&lt;6&gt;?J+.:=/&amp;%#0$1C23#</text>
<text top="149" left="124" width="48" height="8" font="40">=&lt;6&gt;?J+@:=&lt;:#0(1C23#</text>
<text top="139" left="114" width="58" height="8" font="40">=&lt;6&gt;?J+&lt;:J,F5-*#0(1(23#</text>
<text top="129" left="103" width="69" height="8" font="40">=&lt;6&gt;?J+-?7:,A+,5*/#0(1$23#</text>
<text top="120" left="100" width="73" height="8" font="40">=&lt;6&gt;?J+B:F&gt;*:&lt;/+&gt;?7-&lt;#0(1923#</text>
<text top="405" left="133" width="32" height="10" font="39">K?&lt;/676/&lt;#</text>
<text top="405" left="183" width="29" height="10" font="39">L5?&gt;&lt;56#</text>
<text top="405" left="232" width="25" height="10" font="39">M/,56*#</text>
<text top="405" left="276" width="29" height="10" font="39">N547&gt;F/#</text>
<text top="405" left="324" width="34" height="10" font="39">N:FF#O6:,/#</text>
<text top="405" left="376" width="35" height="10" font="39">M-?#O6:,/#</text>
<text top="452" left="81" width="334" height="12" font="15">Figure 12. Fraction of time spent on major VM activities.</text>
<text top="452" left="419" width="21" height="12" font="4">The</text>
<text top="467" left="81" width="359" height="12" font="4">speedup vs. interpreter is shown in parentheses next to each test.</text>
<text top="482" left="81" width="359" height="12" font="4">Most programs where the VM spends the majority of its time run-</text>
<text top="497" left="81" width="359" height="12" font="4">ning native code have a good speedup. Recording and compilation</text>
<text top="512" left="81" width="359" height="12" font="4">costs can be substantial; speeding up those parts of the implemen-</text>
<text top="527" left="81" width="249" height="12" font="4">tation would improve SunSpider performance.</text>
<text top="598" left="81" width="359" height="12" font="4">inner loops become hot first), leading to much greater tail duplica-</text>
<text top="613" left="81" width="24" height="12" font="4">tion.</text>
<text top="628" left="99" width="341" height="12" font="4">YETI, from Zaleski et al. (19) applied Dynamo-style tracing</text>
<text top="643" left="81" width="359" height="12" font="4">to Java in order to achieve inlining, indirect jump elimination,</text>
<text top="658" left="81" width="359" height="12" font="4">and other optimizations. Their primary focus was on designing an</text>
<text top="673" left="81" width="359" height="12" font="4">interpreter that could easily be gradually re-engineered as a tracing</text>
<text top="688" left="81" width="25" height="12" font="4">VM.</text>
<text top="703" left="99" width="344" height="12" font="4">Suganuma et al. (18) described region-based compilation (RBC),</text>
<text top="718" left="81" width="359" height="12" font="4">a relative of tracing. A region is an subprogram worth optimizing</text>
<text top="733" left="81" width="359" height="12" font="4">that can include subsets of any number of methods. Thus, the com-</text>
<text top="747" left="81" width="359" height="12" font="4">piler has more flexibility and can potentially generate better code,</text>
<text top="762" left="81" width="359" height="12" font="4">but the profiling and compilation systems are correspondingly more</text>
<text top="777" left="81" width="49" height="12" font="4">complex.</text>
<text top="792" left="99" width="258" height="12" font="15">Type specialization for dynamic languages.</text>
<text top="792" left="363" width="77" height="12" font="4">Dynamic lan-</text>
<text top="807" left="81" width="359" height="12" font="4">guage implementors have long recognized the importance of type</text>
<text top="822" left="81" width="359" height="12" font="4">specialization for performance. Most previous work has focused on</text>
<text top="837" left="81" width="140" height="12" font="4">methods instead of traces.</text>
<text top="852" left="99" width="341" height="12" font="4">Chambers et. al (9) pioneered the idea of compiling multiple</text>
<text top="867" left="81" width="359" height="12" font="4">versions of a procedure specialized for the input types in the lan-</text>
<text top="882" left="81" width="359" height="12" font="4">guage Self. In one implementation, they generated a specialized</text>
<text top="897" left="81" width="359" height="12" font="4">method online each time a method was called with new input types.</text>
<text top="912" left="81" width="359" height="12" font="4">In another, they used an offline whole-program static analysis to</text>
<text top="927" left="81" width="359" height="12" font="4">infer input types and constant receiver types at call sites. Interest-</text>
<text top="942" left="81" width="350" height="12" font="4">ingly, the two techniques produced nearly the same performance.</text>
<text top="957" left="99" width="341" height="12" font="4">Salib (17) designed a type inference algorithm for Python based</text>
<text top="972" left="81" width="359" height="12" font="4">on the Cartesian Product Algorithm and used the results to special-</text>
<text top="987" left="81" width="249" height="12" font="4">ize on types and translate the program to C++.</text>
<text top="1001" left="99" width="341" height="12" font="4">McCloskey (14) has work in progress based on a language-</text>
<text top="1016" left="81" width="359" height="12" font="4">independent type inference that is used to generate efficient C</text>
<text top="1031" left="81" width="285" height="12" font="4">implementations of JavaScript and Python programs.</text>
<text top="1046" left="99" width="225" height="12" font="15">Native code generation by interpreters.</text>
<text top="1046" left="327" width="112" height="12" font="4">The traditional inter-</text>
<text top="1061" left="81" width="359" height="12" font="4">preter design is a virtual machine that directly executes ASTs or</text>
<text top="1076" left="81" width="359" height="12" font="4">machine-code-like bytecodes. Researchers have shown how to gen-</text>
<text top="111" left="476" width="359" height="12" font="4">erate native code with nearly the same structure but better perfor-</text>
<text top="126" left="476" width="38" height="12" font="4">mance.</text>
<text top="141" left="493" width="341" height="12" font="4">Call threading, also known as context threading (8), compiles</text>
<text top="156" left="476" width="359" height="12" font="4">methods by generating a native call instruction to an interpreter</text>
<text top="171" left="476" width="359" height="12" font="4">method for each interpreter bytecode. A call-return pair has been</text>
<text top="186" left="476" width="359" height="12" font="4">shown to be a potentially much more efficient dispatch mechanism</text>
<text top="201" left="476" width="334" height="12" font="4">than the indirect jumps used in standard bytecode interpreters.</text>
<text top="215" left="493" width="341" height="12" font="4">Inline threading (15) copies chunks of interpreter native code</text>
<text top="230" left="476" width="359" height="12" font="4">which implement the required bytecodes into a native code cache,</text>
<text top="245" left="476" width="359" height="12" font="4">thus acting as a simple per-method JIT compiler that eliminates the</text>
<text top="260" left="476" width="100" height="12" font="4">dispatch overhead.</text>
<text top="275" left="493" width="341" height="12" font="4">Neither call threading nor inline threading perform type special-</text>
<text top="290" left="476" width="40" height="12" font="4">ization.</text>
<text top="305" left="493" width="341" height="12" font="4">Apple’s SquirrelFish Extreme (5) is a JavaScript implementa-</text>
<text top="320" left="476" width="359" height="12" font="4">tion based on call threading with selective inline threading. Com-</text>
<text top="335" left="476" width="359" height="12" font="4">bined with efficient interpreter engineering, these threading tech-</text>
<text top="350" left="476" width="359" height="12" font="4">niques have given SFX excellent performance on the standard Sun-</text>
<text top="365" left="476" width="107" height="12" font="4">Spider benchmarks.</text>
<text top="380" left="493" width="341" height="12" font="4">Google’s V8 is a JavaScript implementation primarily based</text>
<text top="395" left="476" width="359" height="12" font="4">on inline threading, with call threading only for very complex</text>
<text top="410" left="476" width="59" height="12" font="4">operations.</text>
<text top="439" left="476" width="12" height="15" font="9">9.</text>
<text top="439" left="504" width="85" height="15" font="9">Conclusions</text>
<text top="463" left="476" width="359" height="12" font="4">This paper described how to run dynamic languages efficiently by</text>
<text top="477" left="476" width="359" height="12" font="4">recording hot traces and generating type-specialized native code.</text>
<text top="492" left="476" width="359" height="12" font="4">Our technique focuses on aggressively inlined loops, and for each</text>
<text top="507" left="476" width="359" height="12" font="4">loop, it generates a tree of native code traces representing the</text>
<text top="522" left="476" width="359" height="12" font="4">paths and value types through the loop observed at run time. We</text>
<text top="537" left="476" width="359" height="12" font="4">explained how to identify loop nesting relationships and generate</text>
<text top="552" left="476" width="359" height="12" font="4">nested traces in order to avoid excessive code duplication due</text>
<text top="567" left="476" width="359" height="12" font="4">to the many paths through a loop nest. We described our type</text>
<text top="582" left="476" width="359" height="12" font="4">specialization algorithm. We also described our trace compiler,</text>
<text top="597" left="476" width="359" height="12" font="4">which translates a trace from an intermediate representation to</text>
<text top="612" left="476" width="231" height="12" font="4">optimized native code in two linear passes.</text>
<text top="627" left="493" width="341" height="12" font="4">Our experimental results show that in practice loops typically</text>
<text top="642" left="476" width="359" height="12" font="4">are entered with only a few different combinations of value types</text>
<text top="657" left="476" width="359" height="12" font="4">of variables. Thus, a small number of traces per loop is sufficient</text>
<text top="672" left="476" width="359" height="12" font="4">to run a program efficiently. Our experiments also show that on</text>
<text top="687" left="476" width="351" height="12" font="4">programs amenable to tracing, we achieve speedups of 2x to 20x.</text>
<text top="716" left="476" width="21" height="15" font="9">10.</text>
<text top="716" left="513" width="92" height="15" font="9">Future Work</text>
<text top="739" left="476" width="359" height="12" font="4">Work is underway in a number of areas to further improve the</text>
<text top="754" left="476" width="359" height="12" font="4">performance of our trace-based JavaScript compiler. We currently</text>
<text top="769" left="476" width="359" height="12" font="4">do not trace across recursive function calls, but plan to add the</text>
<text top="784" left="476" width="359" height="12" font="4">support for this capability in the near term. We are also exploring</text>
<text top="799" left="476" width="359" height="12" font="4">adoption of the existing work on tree recompilation in the context</text>
<text top="814" left="476" width="359" height="12" font="4">of the presented dynamic compiler in order to minimize JIT pause</text>
<text top="829" left="476" width="359" height="12" font="4">times and obtain the best of both worlds, fast tree stitching as well</text>
<text top="844" left="476" width="297" height="12" font="4">as the improved code quality due to tree recompilation.</text>
<text top="859" left="493" width="341" height="12" font="4">We also plan on adding support for tracing across regular ex-</text>
<text top="874" left="476" width="359" height="12" font="4">pression substitutions using lambda functions, function applica-</text>
<text top="889" left="476" width="211" height="12" font="4">tions and expression evaluation using</text>
<text top="890" left="692" width="28" height="11" font="7">eval</text>
<text top="889" left="720" width="114" height="12" font="4">. All these language</text>
<text top="904" left="476" width="359" height="12" font="4">constructs are currently executed via interpretation, which limits</text>
<text top="919" left="476" width="303" height="12" font="4">our performance for applications that use those features.</text>
<text top="948" left="476" width="129" height="15" font="9">Acknowledgments</text>
<text top="972" left="476" width="359" height="12" font="4">Parts of this effort have been sponsored by the National Science</text>
<text top="987" left="476" width="359" height="12" font="4">Foundation under grants CNS-0615443 and CNS-0627747, as well</text>
<text top="1001" left="476" width="359" height="12" font="4">as by the California MICRO Program and industrial sponsor Sun</text>
<text top="1016" left="476" width="219" height="12" font="4">Microsystems under Project No. 07-127.</text>
<text top="1031" left="493" width="341" height="12" font="4">The U.S. Government is authorized to reproduce and distribute</text>
<text top="1046" left="476" width="359" height="12" font="4">reprints for Governmental purposes notwithstanding any copyright</text>
<text top="1061" left="476" width="359" height="12" font="4">annotation thereon. Any opinions, findings, and conclusions or rec-</text>
<text top="1076" left="476" width="359" height="12" font="4">ommendations expressed here are those of the author and should</text>
</page>
<page number="14" position="absolute" top="0" left="0" height="1188" width="918">
	<fontspec id="41" size="12" family="FCXRUF+NimbusRomNo9L-ReguItal" color="#000000"/>
<text top="111" left="81" width="359" height="12" font="4">not be interpreted as necessarily representing the official views,</text>
<text top="126" left="81" width="359" height="12" font="4">policies or endorsements, either expressed or implied, of the Na-</text>
<text top="141" left="81" width="359" height="12" font="4">tional Science foundation (NSF), any other agency of the U.S. Gov-</text>
<text top="156" left="81" width="278" height="12" font="4">ernment, or any of the companies mentioned above.</text>
<text top="185" left="81" width="76" height="15" font="9">References</text>
<text top="207" left="87" width="54" height="11" font="21">[1] LuaJIT</text>
<text top="207" left="156" width="42" height="11" font="21">roadmap</text>
<text top="207" left="212" width="24" height="11" font="21">2008</text>
<text top="207" left="251" width="4" height="11" font="21">-</text>
<text top="207" left="270" width="169" height="11" font="21">http://lua-users.org/lists/lua-l/2008-</text>
<text top="221" left="106" width="93" height="11" font="21">02/msg00051.html.</text>
<text top="238" left="87" width="353" height="11" font="21">[2] Mozilla — Firefox web browser and Thunderbird email client -</text>
<text top="252" left="106" width="119" height="11" font="21">http://www.mozilla.com.</text>
<text top="270" left="87" width="230" height="11" font="21">[3] SPECJVM98 - http://www.spec.org/jvm98/.</text>
<text top="287" left="87" width="90" height="11" font="21">[4] SpiderMonkey</text>
<text top="287" left="229" width="69" height="11" font="21">(JavaScript-C)</text>
<text top="287" left="350" width="34" height="11" font="21">Engine</text>
<text top="287" left="436" width="4" height="11" font="21">-</text>
<text top="301" left="106" width="200" height="11" font="21">http://www.mozilla.org/js/spidermonkey/.</text>
<text top="318" left="87" width="353" height="11" font="21">[5] Surfin’ Safari - Blog Archive - Announcing SquirrelFish Extreme -</text>
<text top="332" left="106" width="291" height="11" font="21">http://webkit.org/blog/214/introducing-squirrelfish-extreme/.</text>
<text top="349" left="87" width="353" height="11" font="21">[6] A. Aho, R. Sethi, J. Ullman, and M. Lam. Compilers: Principles,</text>
<text top="363" left="106" width="133" height="11" font="21">techniques, and tools, 2006.</text>
<text top="380" left="87" width="353" height="11" font="21">[7] V. Bala, E. Duesterwald, and S. Banerjia. Dynamo: A transparent</text>
<text top="394" left="106" width="160" height="11" font="21">dynamic optimization system. In</text>
<text top="394" left="270" width="170" height="10" font="41">Proceedings of the ACM SIGPLAN</text>
<text top="407" left="106" width="331" height="10" font="41">Conference on Programming Language Design and Implementation</text>
<text top="407" left="437" width="3" height="11" font="21">,</text>
<text top="420" left="106" width="148" height="11" font="21">pages 1–12. ACM Press, 2000.</text>
<text top="438" left="87" width="353" height="11" font="21">[8] M. Berndl, B. Vitale, M. Zaleski, and A. Brown. Context Threading:</text>
<text top="451" left="106" width="334" height="11" font="21">a Flexible and Efficient Dispatch Technique for Virtual Machine In-</text>
<text top="465" left="106" width="65" height="11" font="21">terpreters. In</text>
<text top="465" left="175" width="265" height="10" font="41">Code Generation and Optimization, 2005. CGO 2005.</text>
<text top="478" left="106" width="135" height="10" font="41">International Symposium on</text>
<text top="478" left="242" width="99" height="11" font="21">, pages 15–26, 2005.</text>
<text top="496" left="87" width="353" height="11" font="21">[9] C. Chambers and D. Ungar. Customization: Optimizing Compiler</text>
<text top="509" left="106" width="334" height="11" font="21">Technology for SELF, a Dynamically-Typed O bject-Oriented Pro-</text>
<text top="523" left="106" width="124" height="11" font="21">gramming Language. In</text>
<text top="523" left="236" width="204" height="10" font="41">Proceedings of the ACM SIGPLAN 1989</text>
<text top="536" left="106" width="331" height="10" font="41">Conference on Programming Language Design and Implementation</text>
<text top="536" left="437" width="3" height="11" font="21">,</text>
<text top="550" left="106" width="241" height="11" font="21">pages 146–160. ACM New York, NY, USA, 1989.</text>
<text top="112" left="476" width="61" height="11" font="21">[10] A. Gal.</text>
<text top="112" left="543" width="291" height="10" font="41">Efficient Bytecode Verification and Compilation in a Virtual</text>
<text top="125" left="501" width="105" height="10" font="41">Machine Dissertation</text>
<text top="125" left="606" width="229" height="11" font="21">. PhD thesis, University Of California, Irvine,</text>
<text top="139" left="501" width="27" height="11" font="21">2006.</text>
<text top="157" left="476" width="359" height="11" font="21">[11] A. Gal, C. W. Probst, and M. Franz. HotpathVM: An effective JIT</text>
<text top="170" left="501" width="211" height="11" font="21">compiler for resource-constrained devices.</text>
<text top="170" left="724" width="10" height="11" font="21">In</text>
<text top="170" left="740" width="94" height="10" font="41">Proceedings of the</text>
<text top="184" left="501" width="299" height="10" font="41">International Conference on Virtual Execution Environments</text>
<text top="184" left="799" width="35" height="11" font="21">, pages</text>
<text top="197" left="501" width="136" height="11" font="21">144–153. ACM Press, 2006.</text>
<text top="215" left="476" width="359" height="11" font="21">[12] C. Garrett, J. Dean, D. Grove, and C. Chambers. Measurement and</text>
<text top="228" left="501" width="289" height="11" font="21">Application of Dynamic Receiver Class Distributions. 1994.</text>
<text top="246" left="476" width="359" height="11" font="21">[13] J. Ha, M. R. Haghighat, S. Cong, and K. S. McKinley. A concurrent</text>
<text top="260" left="501" width="334" height="11" font="21">trace-based just-in-time compiler for javascript. Dept.of Computer</text>
<text top="273" left="501" width="295" height="11" font="21">Sciences, The University of Texas at Austin, TR-09-06, 2009.</text>
<text top="291" left="476" width="222" height="11" font="21">[14] B. McCloskey. Personal communication.</text>
<text top="309" left="476" width="359" height="11" font="21">[15] I. Piumarta and F. Riccardi. Optimizing direct threaded code by selec-</text>
<text top="323" left="501" width="77" height="11" font="21">tive inlining. In</text>
<text top="323" left="581" width="253" height="10" font="41">Proceedings of the ACM SIGPLAN 1998 conference</text>
<text top="336" left="501" width="270" height="10" font="41">on Programming language design and implementation</text>
<text top="336" left="771" width="64" height="11" font="21">, pages 291–</text>
<text top="349" left="501" width="187" height="11" font="21">300. ACM New York, NY, USA, 1998.</text>
<text top="367" left="476" width="359" height="11" font="21">[16] A. Rigo. Representation-Based Just-In-time Specialization and the</text>
<text top="381" left="501" width="149" height="11" font="21">Psyco Prototype for Python. In</text>
<text top="381" left="653" width="32" height="10" font="41">PEPM</text>
<text top="381" left="685" width="33" height="11" font="21">, 2004.</text>
<text top="399" left="476" width="72" height="11" font="21">[17] M. Salib.</text>
<text top="399" left="561" width="274" height="11" font="21">Starkiller: A Static Type Inferencer and Compiler for</text>
<text top="412" left="501" width="51" height="11" font="21">Python. In</text>
<text top="412" left="555" width="76" height="10" font="41">Master’s Thesis</text>
<text top="412" left="630" width="33" height="11" font="21">, 2004.</text>
<text top="430" left="476" width="359" height="11" font="21">[18] T. Suganuma, T. Yasue, and T. Nakatani. A Region-Based Compila-</text>
<text top="444" left="501" width="195" height="11" font="21">tion Technique for Dynamic Compilers.</text>
<text top="444" left="703" width="132" height="10" font="41">ACM Transactions on Pro-</text>
<text top="457" left="501" width="219" height="10" font="41">gramming Languages and Systems (TOPLAS)</text>
<text top="457" left="720" width="110" height="11" font="21">, 28(1):134–174, 2006.</text>
<text top="475" left="476" width="248" height="11" font="21">[19] M. Zaleski, A. D. Brown, and K. Stoodley.</text>
<text top="475" left="736" width="98" height="11" font="21">YETI: A graduallY</text>
<text top="488" left="501" width="142" height="11" font="21">Extensible Trace Interpreter.</text>
<text top="488" left="655" width="10" height="11" font="21">In</text>
<text top="489" left="671" width="163" height="10" font="41">Proceedings of the International</text>
<text top="502" left="501" width="230" height="10" font="41">Conference on Virtual Execution Environments</text>
<text top="502" left="731" width="103" height="11" font="21">, pages 83–93. ACM</text>
<text top="515" left="501" width="58" height="11" font="21">Press, 2007.</text>
</page>
</pdf2xml>
