Home | History | Annotate | Download | only in dalvik
      1 page.title=Implementing ART Just-In-Time (JIT) Compiler
      2 @jd:body
      3 
      4 <!--
      5     Copyright 2016 The Android Open Source Project
      6 
      7     Licensed under the Apache License, Version 2.0 (the "License");
      8     you may not use this file except in compliance with the License.
      9     You may obtain a copy of the License at
     10 
     11         http://www.apache.org/licenses/LICENSE-2.0
     12 
     13     Unless required by applicable law or agreed to in writing, software
     14     distributed under the License is distributed on an "AS IS" BASIS,
     15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16     See the License for the specific language governing permissions and
     17     limitations under the License.
     18 -->
     19 
     20 
     21 <div id="qv-wrapper">
     22 <div id="qv">
     23   <h2 id="Contents">In this document</h2>
     24   <ol id="auto-toc">
     25   </ol>
     26 </div>
     27 </div>
     28 
     29 <p>
     30 Android 7.0 adds a just-in-time (JIT) compiler with code profiling to Android
     31 runtime (ART) that constantly improves the performance of Android apps as they
     32 run. The JIT compiler complements ART's current ahead-of-time (AOT) compiler and
     33 improves runtime performance, saves storage space, and speeds app updates and
     34 system updates.
     35 </p>
     36 
     37 <p>
     38 The JIT compiler also improves upon the AOT compiler by avoiding system slowdown
     39 during automatic application updates or recompilation of applications during
     40 OTAs. This feature should require minimal device integration on the part of
     41 manufacturers.
     42 </p>
     43 
     44 <p>
     45 JIT and AOT use the same compiler with an almost identical set of optimizations.
     46 The generated code might not be the same but it depends. JIT makes uses of
     47 runtime type information and can do better inlining. Also, with JIT we sometimes
     48 do OSR compilation (on stack replacement) which will again generate a bit
     49 different code.
     50 </p>
     51 
     52 <p>
     53 See <a
     54 href="https://developer.android.com/preview/api-overview.html#jit_aot">Profile-guided
     55 JIT/AOT Compilation</a> on developer.android.com for a more thorough overview.
     56 </p>
     57 
     58 <h2 id="architectural-overview">Architectural Overview</h2>
     59 
     60 <img src="images/jit-arch.png" alt="JIT architecture" width="633" id="JIT-architecture" />
     61 <p class="img-caption">
     62   <strong>Figure 1.</strong> JIT architecture - how it works
     63 </p>
     64 
     65 <h2 id="flow">Flow</h2>
     66 
     67 <p>
     68 JIT compilation works in this manner:
     69 </p>
     70 
     71 <ol>
     72 <li>The user runs the app, which then triggers ART to load the .dex file.
     73 <li>If the .oat file (the AOT binary for the .dex file) is available, ART uses
     74 them directly. Note that .oat files are generated regularly. However, that does
     75 not imply they contain compiled code (AOT binary).
     76 <li>If no .oat file is available, ART runs through either JIT or an interpreter
     77 to execute the .dex file. ART will always use the .oat files if available.
     78 Otherwise, it will use the APK and extract it in memory to get to the .dex
     79 incurring a big memory overhead (equal to the size of the dex files).
     80 <li>JIT is enabled for any application that is not compiled according to the
     81 "speed" compilation filter (which says, compile as much as you can from the
     82 app).
     83 <li>The JIT profile data is dumped to a file in a system directory. Only the
     84 application has access to the directory.
     85 <li>The AOT compilation (dex2oat) daemon parses that file to drive its
     86 compilation.</li>
     87 </ol>
     88 
     89 <img src="images/jit-profile-comp.png" alt="Profile-guided comp" width="452" id="JIT-profile-comp" />
     90 <p class="img-caption">
     91   <strong>Figure 2.</strong> Profile-guided compilation
     92 </p>
     93 
     94 <img src="images/jit-daemon.png" alt="JIT daemon" width="718" id="JIT-daemon" />
     95 <p class="img-caption">
     96   <strong>Figure 3.</strong> How the daemon works
     97 </p>
     98 
     99 <p>
    100 The Google Play service is an example used by other apps. These application tend
    101 to behave more like shared libraries.
    102 </p>
    103 
    104 <h2 id="jit-workflow">JIT Workflow</h2>
    105 <p>
    106 See the following high-level overview of how JIT works in the next diagram.
    107 </p>
    108 
    109 <img src="images/jit-workflow.png" alt="JIT architecture" width="707" id="JIT-workflow" />
    110 <p class="img-caption">
    111   <strong>Figure 4.</strong> JIT data flow
    112 </p>
    113 
    114 <p>
    115 This means:
    116 </p>
    117 
    118 <ul>
    119 <li>Profiling information is stored in the code cache and subjected to garbage
    120 collection under memory pressure.
    121 <li>As a result, theres no guarantee the snapshot taken when the application is
    122 in the background will contain the complete data (i.e. everything that was
    123 JITed).
    124 <li>There is no attempt to make sure we record everything as that will impact
    125 runtime performance.
    126 <li>Methods can be in three different states: <ul>
    127  <li>interpreted (dex code)
    128  <li>JIT compiled
    129  <li>AOT compiled
    130 <li>If both, JIT and AOT code exists (e.g. due to repeated de-optimizations),
    131 the JITed code will be preferred.
    132 <li>The memory requirement to run JIT without impacting foreground app
    133 performance depends upon the app in question. Large apps will require more
    134 memory than small apps. In general, big apps stabilize around 4 MB.</li></ul>
    135 </li>
    136 </ul>
    137 
    138 <h2 id="system-properties">System Properties</h2>
    139 
    140 <p>
    141 These system properties control JIT behavior:
    142 </p><ul>
    143 <li><code>dalvik.vm.usejit <true|false></code> - Whether or not the JIT is
    144 enabled.
    145 <li><code>dalvik.vm.jitinitialsize</code> (default 64K) - The initial capacity
    146 of the code cache. The code cache will regularly GC and increase if needed. It
    147 is possible to view the size of the code cache for your app with:<br>
    148 <code> $ adb shell dumpsys meminfo -d &LT;pid&GT;</code>
    149 <li><code>dalvik.vm.jitmaxsize</code> (default 64M) - The maximum capacity of
    150 the code cache.
    151 <li><code>dalvik.vm.jitthreshold &LT;integer&GT;</code> (default 10000) - This
    152 is the threshold that the "hotness" counter of a method needs to pass in order
    153 for the method to be JIT compiled. The "hotness" counter is a metric internal
    154 to the runtime. It includes the number of calls, backward branches & other
    155 factors.
    156 <li><code>dalvik.vm.usejitprofiles &LT;true|false&GT;</code> - Whether or not
    157 JIT profiles are enabled;  this may be used even if usejit is false.
    158 <li><code>dalvik.vm.jitprithreadweight &LT;integer&GT;</code> (default to
    159 <code>dalvik.vm.jitthreshold</code> / 20) - The weight of the JIT "samples"
    160 (see jitthreshold) for the application UI thread. Use to speed up compilation
    161 of methods that directly affect users experience when interacting with the
    162 app.
    163 <li><code>dalvik.vm.jittransitionweight &LT;integer&GT;</code>
    164 (<code>dalvik.vm.jitthreshold</code> / 10) - The weight of the method
    165 invocation that transitions between compile code and interpreter. This helps
    166 make sure the methods involved are compiled to minimize transitions (which are
    167 expensive).
    168 </li>
    169 </ul>
    170 
    171 <h2 id="tuning">Tuning</h2>
    172 
    173 <p>
    174 Partners may precompile (some of) the system apps if they want so. Initial JIT
    175 performance vs pre-compiled depends on the the app, but in general they are
    176 quite close. It might be worth noting that precompiled apps will not be profiled
    177 and as such will take more space and may miss on other optimizations.
    178 </p>
    179 
    180 <p>
    181 In Android 7.0, there's a generic way to specify the level of
    182 compilation/verification based on the different use cases. For example, the
    183 default option for install time is to do only verification (and postpone
    184 compilation to a later stage). The compilation levels can be configured via
    185 system properties with the defaults being:
    186 </p>
    187 
    188 <pre>
    189 pm.dexopt.install=interpret-only
    190 pm.dexopt.bg-dexopt=speed-profile
    191 pm.dexopt.ab-ota=speed-profile
    192 pm.dexopt.nsys-library=speed
    193 pm.dexopt.shared-apk=speed
    194 pm.dexopt.forced-dexopt=speed
    195 pm.dexopt.core-app=speed
    196 pm.dexopt.first-boot=interpret-only
    197 pm.dexopt.boot=verify-profile
    198 </pre>
    199 
    200 <p>
    201 Note the reference to A/B over-the-air (OTA) updates here.
    202 </p>
    203 
    204 <p>
    205 Check <code>$ adb shell cmd package compile</code> for usage. Note all commands
    206 are preceded by a dollar ($) sign that should be excluded when copying and
    207 pasting. A few common use cases:
    208 </p>
    209 
    210 <h3 id="turn-on-jit-logging">Turn on JIT logging</h3>
    211 
    212 <pre>
    213 $ adb root
    214 $ adb shell stop
    215 $ adb shell setprop dalvik.vm.extra-opts -verbose:jit
    216 $ adb shell start
    217 </pre>
    218 
    219 <h3 id="disable-jit-and-run-applications-in-interpreter">Disable JIT</h3>
    220 
    221 <pre>
    222 $ adb root
    223 $ adb shell stop
    224 $ adb shell setprop dalvik.vm.usejit false
    225 $ adb shell start
    226 </pre>
    227 
    228 <h3 id="force-compilation-of-a-specific-package">Force compilation of a specific
    229 package</h3>
    230 
    231 <ul>
    232 <li>Profile-based:
    233 <code>$ adb shell cmd package compile -m speed-profile -f
    234 my-package</code>
    235 <li>Full:
    236 <code>$ adb shell cmd package compile -m speed -f
    237 my-package</code></li>
    238 </ul>
    239 
    240 <h3 id="force-compilation-of-all-packages">Force compilation of all
    241 packages</h3>
    242 
    243 <ul>
    244 <li>Profile-based:
    245 <code>$ adb shell cmd package compile -m speed-profile -f
    246 -a</code>
    247 <li>Full:
    248 <code>$ adb shell cmd package compile -m speed -f -a</code></li></ul>
    249 
    250 <h3 id="clear-profile-data-and-remove-compiled-code">Clear profile data and
    251 remove compiled code</h3>
    252 
    253 <ul>
    254 <li>One package:
    255 <code>$ adb shell cmd package compile --reset my-package</code>
    256 <li>All packages
    257 <code>$ adb shell cmd package compile --reset
    258 -a</code></li>
    259 </ul>
    260 
    261 <h2 id="validation">Validation</h2>
    262 
    263 <p>
    264 To ensure their version of the feature works as intended, partners should run
    265 the ART test in <code>android/art/test</code>. Also, see the CTS test
    266 <code>hostsidetests/compilation</code> for userdedug builds.
    267 </p>
    268