blob: 74ac6de0c6a7ea9faadd73605275790386576d80 [file] [log] [blame]
<html devsite>
<head>
<title>Implementing ART Just-In-Time (JIT) Compiler</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
<body>
<!--
Copyright 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>
Android 7.0 adds a just-in-time (JIT) compiler with code profiling to Android
runtime (ART) that constantly improves the performance of Android apps as they
run. The JIT compiler complements ART's current ahead-of-time (AOT) compiler and
improves runtime performance, saves storage space, and speeds app updates and
system updates.
</p>
<p>
The JIT compiler also improves upon the AOT compiler by avoiding system slowdown
during automatic application updates or recompilation of applications during
OTAs. This feature should require minimal device integration on the part of
manufacturers.
</p>
<p>
JIT and AOT use the same compiler with an almost identical set of optimizations.
The generated code might not be the same but it depends. JIT makes uses of
runtime type information and can do better inlining. Also, with JIT we sometimes
do OSR compilation (on stack replacement) which will again generate a bit
different code.
</p>
<h2 id="architectural-overview">Architectural Overview</h2>
<img src="/devices/tech/dalvik/images/jit-arch.png" alt="JIT architecture" width="633" id="JIT-architecture" />
<p class="img-caption">
<strong>Figure 1.</strong> JIT architecture - how it works
</p>
<h2 id="flow">Flow</h2>
<p>
JIT compilation works in this manner:
</p>
<ol>
<li>The user runs the app, which then triggers ART to load the .dex file.
<li>If the .oat file (the AOT binary for the .dex file) is available, ART uses
them directly. Note that .oat files are generated regularly. However, that does
not imply they contain compiled code (AOT binary).
<li>If no .oat file is available, ART runs through either JIT or an interpreter
to execute the .dex file. ART will always use the .oat files if available.
Otherwise, it will use the APK and extract it in memory to get to the .dex
incurring a big memory overhead (equal to the size of the dex files).
<li>JIT is enabled for any application that is not compiled according to the
"speed" compilation filter (which says, compile as much as you can from the
app).
<li>The JIT profile data is dumped to a file in a system directory. Only the
application has access to the directory.
<li>The AOT compilation (dex2oat) daemon parses that file to drive its
compilation.</li>
</ol>
<img src="/devices/tech/dalvik/images/jit-profile-comp.png" alt="Profile-guided comp" width="452" id="JIT-profile-comp" />
<p class="img-caption">
<strong>Figure 2.</strong> Profile-guided compilation
</p>
<img src="/devices/tech/dalvik/images/jit-daemon.png" alt="JIT daemon" width="718" id="JIT-daemon" />
<p class="img-caption">
<strong>Figure 3.</strong> How the daemon works
</p>
<p>
The Google Play service is an example used by other apps. These application tend
to behave more like shared libraries.
</p>
<h2 id="jit-workflow">JIT Workflow</h2>
<p>
See the following high-level overview of how JIT works in the next diagram.
</p>
<img src="/devices/tech/dalvik/images/jit-workflow.png" alt="JIT architecture" width="707" id="JIT-workflow" />
<p class="img-caption">
<strong>Figure 4.</strong> JIT data flow
</p>
<p>
This means:
</p>
<ul>
<li>Profiling information is stored in the code cache and subjected to garbage
collection under memory pressure.
<li>As a result, there’s no guarantee the snapshot taken when the application is
in the background will contain the complete data (i.e. everything that was
JITed).
<li>There is no attempt to make sure we record everything as that will impact
runtime performance.
<li>Methods can be in three different states: <ul>
<li>interpreted (dex code)
<li>JIT compiled
<li>AOT compiled
<li>If both, JIT and AOT code exists (e.g. due to repeated de-optimizations),
the JITed code will be preferred.
<li>The memory requirement to run JIT without impacting foreground app
performance depends upon the app in question. Large apps will require more
memory than small apps. In general, big apps stabilize around 4 MB.</li></ul>
</li>
</ul>
<h2 id="tuning">Useful tips</h2>
<h3 id="turn-on-jit-logging">Turn on JIT logging</h3>
<pre class="devsite-click-to-copy">
<code class="devsite-terminal">adb root</code>
<code class="devsite-terminal">adb shell stop</code>
<code class="devsite-terminal">adb shell setprop dalvik.vm.extra-opts -verbose:jit</code>
<code class="devsite-terminal">adb shell start</code>
</pre>
<h3 id="disable-jit-and-run-applications-in-interpreter">Disable JIT</h3>
<pre class="devsite-click-to-copy">
<code class="devsite-terminal">adb root</code>
<code class="devsite-terminal">adb shell stop</code>
<code class="devsite-terminal">adb shell setprop dalvik.vm.usejit false</code>
<code class="devsite-terminal">adb shell start</code>
</pre>
<h3 id="force-compilation-of-a-specific-package">Force compilation of a specific
package</h3>
<p>
Check <code>$ adb shell cmd package compile</code> for usage. A few common use cases:
</p>
<ul>
<li>Profile-based:
<pre class="devsite-terminal devsite-click-to-copy">
adb shell cmd package compile -m speed-profile -f my-package
</pre>
</li>
<li>Full:
<pre class="devsite-terminal devsite-click-to-copy">
adb shell cmd package compile -m speed -f my-package
</pre>
</li>
</ul>
<h3 id="force-compilation-of-all-packages">Force compilation of all
packages</h3>
<ul>
<li>Profile-based:
<pre class="devsite-terminal devsite-click-to-copy">
adb shell cmd package compile -m speed-profile -f -a
</pre>
</li>
<li>Full:
<pre class="devsite-terminal devsite-click-to-copy">
adb shell cmd package compile -m speed -f -a
</pre>
</li>
</ul>
<h3 id="clear-profile-data-and-remove-compiled-code">Clear profile data and
remove compiled code</h3>
<ul>
<li>One package:
<pre class="devsite-terminal devsite-click-to-copy">
adb shell cmd package compile --reset my-package
</pre>
</li>
<li>All packages
<pre class="devsite-terminal devsite-click-to-copy">
adb shell cmd package compile --reset -a
</pre>
</li>
</ul>
</body>
</html>