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 <pid></code> 149 <li><code>dalvik.vm.jitmaxsize</code> (default 64M) - The maximum capacity of 150 the code cache. 151 <li><code>dalvik.vm.jitthreshold <integer></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 <true|false></code> - Whether or not 157 JIT profiles are enabled; this may be used even if usejit is false. 158 <li><code>dalvik.vm.jitprithreadweight <integer></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 <integer></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