blob: 00f26e4ce21b892d62d8b9efde9277a0fc979074 [file] [log] [blame]
Clay Murphy87d3bb52016-07-08 12:03:55 -07001page.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>
30Android N adds a just-in-time (JIT) compiler with code profiling to Android
31runtime (ART) that constantly improves the performance of Android apps as they
32run. The JIT compiler complements ART's current ahead-of-time (AOT) compiler and
33improves runtime performance, saves storage space, and speeds app updates and
34system updates.
35</p>
36
37<p>
38The JIT compiler also improves upon the AOT compiler by avoiding system slowdown
39during automatic application updates or recompilation of applications during
40OTAs. This feature should require minimal device integration on the part of
41manufacturers.
42</p>
43
44<p>
45JIT and AOT use the same compiler with an almost identical set of optimizations.
46The generated code might not be the same but it depends. JIT makes uses of
47runtime type information and can do better inlining. Also, with JIT we sometimes
48do OSR compilation (on stack replacement) which will again generate a bit
49different code.
50</p>
51
52<p>
53See <a
54href="https://developer.android.com/preview/api-overview.html#jit_aot">Profile-guided
55JIT/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>
68JIT 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
74them directly. Note that .oat files are generated regularly. However, that does
75not imply they contain compiled code (AOT binary).
76<li>If no .oat file is available, ART runs through either JIT or an interpreter
77to execute the .dex file. ART will always use the .oat files if available.
78Otherwise, it will use the APK and extract it in memory to get to the .dex
79incurring 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
82app).
83<li>The JIT profile data is dumped to a file in a system directory. Only the
84application has access to the directory.
85<li>The AOT compilation (dex2oat) daemon parses that file to drive its
86compilation.</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>
100The Google Play service is an example used by other apps. These application tend
101to behave more like shared libraries.
102</p>
103
104<h2 id="jit-workflow">JIT Workflow</h2>
105<p>
106See 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>
115This means:
116</p>
117
118<ul>
119<li>Profiling information is stored in the code cache and subjected to garbage
120collection under memory pressure.
121<li>As a result, there’s no guarantee the snapshot taken when the application is
122in the background will contain the complete data (i.e. everything that was
123JITed).
124<li>There is no attempt to make sure we record everything as that will impact
125runtime 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),
131the JITed code will be preferred.
132<li>The memory requirement to run JIT without impacting foreground app
133performance depends upon the app in question. Large apps will require more
134memory 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>
141These system properties control JIT behavior:
142</p><ul>
143<li><code>dalvik.vm.usejit <true|false></code> - Whether or not the JIT is
144enabled.
145<li><code>dalvik.vm.jitinitialsize</code> (default 64K) - The initial capacity
146of the code cache. The code cache will regularly GC and increase if needed. It
147is 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
150the code cache.
151<li><code>dalvik.vm.jitthreshold &LT;integer&GT;</code> (default 10000) - This
152is the threshold that the "hotness" counter of a method needs to pass in order
153for the method to be JIT compiled. The "hotness" counter is a metric internal
154to the runtime. It includes the number of calls, backward branches & other
155factors.
156<li><code>dalvik.vm.usejitprofiles &LT;true|false&GT;</code> - Whether or not
157JIT 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
161of methods that directly affect users experience when interacting with the
162app.
163<li><code>dalvik.vm.jittransitionweight &LT;integer&GT;</code>
164(<code>dalvik.vm.jitthreshold</code> / 10) - The weight of the method
165invocation that transitions between compile code and interpreter. This helps
166make sure the methods involved are compiled to minimize transitions (which are
167expensive).
168</li>
169</ul>
170
171<h2 id="tuning">Tuning</h2>
172
173<p>
174Partners may precompile (some of) the system apps if they want so. Initial JIT
175performance vs pre-compiled depends on the the app, but in general they are
176quite close. It might be worth noting that precompiled apps will not be profiled
177and as such will take more space and may miss on other optimizations.
178</p>
179
180<p>
181In Android N, there's a generic way to specify the level of
182compilation/verification based on the different use cases. For example, the
183default option for install time is to do only verification (and postpone
184compilation to a later stage). The compilation levels can be configured via
185system properties with the defaults being:
186</p>
187
188<pre>
189pm.dexopt.install=interpret-only
190pm.dexopt.bg-dexopt=speed-profile
191pm.dexopt.ab-ota=speed-profile
192pm.dexopt.nsys-library=speed
193pm.dexopt.shared-apk=speed
194pm.dexopt.forced-dexopt=speed
195pm.dexopt.core-app=speed
196pm.dexopt.first-boot=interpret-only
197pm.dexopt.boot=verify-profile
198</pre>
199
200<p>
201Note the reference to A/B over-the-air (OTA) updates here.
202</p>
203
204<p>
205Check <code>$ adb shell cmd package compile</code> for usage. Note all commands
206are preceded by a dollar ($) sign that should be excluded when copying and
207pasting. 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
229package</h3>
230
231<ul>
232<li>Profile-based:
233<code>$ adb shell cmd package compile -m speed-profile -f
234my-package</code>
235<li>Full:
236<code>$ adb shell cmd package compile -m speed -f
237my-package</code></li>
238</ul>
239
240<h3 id="force-compilation-of-all-packages">Force compilation of all
241packages</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
251remove 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>
264To ensure their version of the feature works as intended, partners should run
265the ART test in <code>android/art/test</code>. Also, see the CTS test
266<code>hostsidetests/compilation</code> for userdedug builds.
267</p>