202 lines
6.6 KiB
HTML
202 lines
6.6 KiB
HTML
<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>
|