Notice:
This post is older than 5 years – the content might be outdated.
This is part one of a small series of articles about the newest Android version Kitkat that I wrote at inovex GmbH. The series is supposed to give you a deeper insight into the internals and changes of Android 4.4 from a developer’s perspective. My job was to start with the new runtime: ART.
Engine inspection: what is the ART
One of KitKats most exciting features is also its less advertised one: the new experimental Runtime, called ART. Google didn’t release much information about it, apart from the fact that it exists. But I think that this feature is likely to have an immense impact on further releases because with ART Android turns its back to its executed dalvik byte-code towards a platform specific, ahead-of-time (AOT) compiled binary code.
The Dalvik VM has followed the traditional Java approach for virtual machines: Source code gets compiled into a platform independent byte code which gets compiled on the fly into machine code (JIT – Just in Time compilation). ART follows a different approach using the AOT paradigm, in which the code gets compiled into native code upfront execution.
But how is that accomplished?
The inter-portability of apps is essential for Android, since there are various platforms with currently three different architectures (MIPS, x86, ARM) on the market. So they had to find a way to combine both worlds: inter-portability and native binary code execution. Their solution is, as far a we know, unique in the mobile world: ship an intermediate byte code executable and perform the last compilation step “ahead-of-time“ on the target device.
A deeper look into the ART sources reveal that they make use of LLVM for the last compilation step. The compilation process to native code is currently done at installation time.
On top of that, the Android team faces another challenge: Compatibility with the existing Dalvik VM/DEX technology. To deal with that, they introduced a way to convert the dex format to their new OAT format. Read on to get more details on this.
A startup-story: from dex to oat
Let’s find out how android is able to execute existing apps on ART without the need of a new app-release. For the following steps I use some new tools that come with the the new runtime:
dex2oat and oatdump, both can be found in <aosproot>out/host/<yourplatform>/bin/dex2oat. In addition to that, some usual linux tools like objdump, nm, hexdump and hexedit were used.
After switching the runtime from Dalivk to ART the bootup process takes a really long time, about 10 minutes, as the system is updating the installed Apps. A closer look at the ADB output shows what is happening: obviously, some kind of image is created by dex2oat.
1 |
I/art ( 123): GenerateImage: /system/bin/dex2oat --image=/data/dalvik-cache/system@framework@boot.art@classes.dex--runtime-arg-Xms64m--runtime-arg-Xmx64m--dex-file=/system/framework/core-libart.jar--dex-file=/system/framework/conscrypt.jar--dex-file=/system/framework/okhttp.jar--dex-file=/system/framework/core-junit.jar--dex-file=/system/framework/bouncycastle.jar--dex-file=/system/framework/ext.jar--dex-file=/system/framework/framework.jar--dex-file=/system/framework/framework2.jar--dex-file=/system/framework/telephony-common.jar--dex-file=/system/framework/voip-common.jar --dex-file=/system/framework/mms-common.jar --dex-file=/system/framework/android.policy.jar --dex-file=/system/framework/services.jar --dex-file=/system/framework/apache-xml.jar --dex-file=/system/framework/webviewchromium.jar --oat-file=/data/dalvik-cache/system@framework@boot.art@classes.oat--base=0x60000000--image-classes-zip=/system/framework/framework.jar--image-classes=preloaded-classes |
A process which logs as art , started by the system_server , creates a huge image file using the dex2oat tool. The commandline arguments suggest split up into the following parts:
- some runtime arguments for a VM
- several DEX files that will be compiled into the image
- the output image filename
- the output oat-filename
- a jar file containing classes that should be compiled into the image
- and a specifier, describing which classes form the jar file should be used
During the image creation, all contained DEX files were compiled. For example:
1 |
W/dex2oat ( 397): Verification of void org.ccil.cowan.tagsoup.HTMLSchema.() took 187.968ms |
Looks familiar, doesn’t it? Remember the zygote in a dalvik driven environment? Basically a boilerplate image that executes the actual application or code and contains frequently used classes. It is definitely no replacement of the zygote, since it still exists in an ART environment, but you can think of it in the same way.
In the further startup process, the package manager runs dexopt on every installed app. But in addition to that, every resulting dex file is compiled into an oat file by the already known dex2oat compiler
Here is an exemplary log of the Keyboard:
1 2 3 |
I/PackageManager(559): Running dexopt on: com.android.inputmethod.latin I/dex2oat (918): dex2oat: /data/dalvik-cache/system@app@LatinIME.apk@classes.dex |
Now let’s summarize what we have so far: we know that ART uses a zygote-like image, which is very likely to execute the actual app later. It also performs a lot of compilation, even on all framework classes. This means that literally the whole system which we know as Android is converted. I think this is a hint that ART is much more than a so-much-better dalvik – it indicates a change of paradigm. But now stay tuned for the next part of our series, where we are going to take a closer look on the new executable file format: OAT file analysis.