Hacker News new | past | comments | ask | show | jobs | submit login
Introducing ART – A new Android runtime being introduced experimentally in 4.4 (android.com)
152 points by alsutton010203 on Nov 1, 2013 | hide | past | favorite | 66 comments

So this is why we haven't seen much happening on the dalvik side.

The source is here: https://android.googlesource.com/platform/art/+/kitkat-relea... and commit log: https://android.googlesource.com/platform/art/+log/kitkat-re... - So if somebody has the time to investigate it most questions should be able to be answered.

The guts are substantially different and seemingly more sophisticated. Notable things:

1) The compiler under compiler/dex seems to do a pretty simple set of optimizations and generate either code directly (compiler/dex/quick) or using LLVM through an intermediate code called GBC (compiler/dex/portable).

2) There's a new file format, OAT. Contrary to some reports, it doesn't appear to be a new bytecode, but rather a new file format for DEX bytecode. My guess it exists to support features like caching generated native code or compiling applications to images that don't have to be JIT-ed. The compiler has support for writing out ELF files, and LLVM can load ELF files dynamically with MCLinker.

3) There seems to be the start of a more sophisticated compiler under compiler/sea_ir. My guess is that it's intended to enable more high-level optimizations in the future. It seems to be a sea-of-nodes IR like the one used in Hotspot's C2 compiler, but doesn't seem to be either finished or plugged in. The change log suggests that it's still getting off the ground.

4) Judging by the commit logs, there seems to be a parallel-marking garbage collector, though otherwise it doesn't seem to be anything fancy.

So I guess no moving GC still, because of LLVM. That's unfortunate.

Does anyone know whether Android/Dalvik has made decisions that lock them into non-moving/conservative GC or whether it's still a possibility in the future?

Google made changes to how the JNI returns references to Java objects in Ice Cream Sandwich (4.0) so that native code can work with a moving GC.


Doesn't answer your question, just some supporting evidence.

Hopefully that means that Google throws some developers at giving LLVM better GC support, so the rest of us benefit.

This is very similar to C#'s NGEN compiler, which compiles C# apps to native code. It's used in Windows Phone to provide pre-compiled versions of applications when people download them.

I thought Dalvik was quiet because the principal author (Dan Bornstein) left Google a while ago.

Is ART from the recent FlexyCore acquisition, or something else that has been going on for a while?

The commit history suggests that it started more than 2 years ago

While Google's acquisition of Flexycore was only made public recently, the process must have started years ago. As Ars Technica noted,


> FlexyCore doesn't seem to have done anything on the Internet for the last two years. The company actively promoted its product, releasing 11 videos in a one-year span, and then just stopped. The lack of recent activity makes it unclear if Flexycore has continued development outside the public eye.

One unfortunate thing about Bornstein leaving is he seemed to be the only one working on fixing the 65536 method limit bug/feature for Dalvik executables.

Tell me about it. All we get is simply spinning methods into separate jars every six months or so. Not a solution, IMO.

Comment from the source[1]:

  We have already created that oat file above with
  CreateOatFile. Originally this was just our own proprietary 
  file but now it is contained within an ELF dynamic object
  (aka an .so file)
Seems like oat file might be enclosed in an ELF container and might support linking of shared libraries.

[1]https://android.googlesource.com/platform/art/+/kitkat-relea... [2]http://www.retrodev.com/android/dexformat.html

Unfortunately that page doesn't actually explain the difference between ART and Dalvik.

I found some random benchmark by a user on XDA (http://www.xda-developers.com/android/new-runtime-compiler-i...) that could indicate significant speedups with ART. Though I would take this information with a huge grain of salt right now as it is one benchmark from an unknown source.

As Android adds more features, more of Android is implemented in Java. Pretty much all of Google Play Services is implemented in Java.

That means Android can rely less on the fact that graphics and the guts of many UI widgets are native code under a thin layer of Java. Android was always a "Java OS" but it has become more so since Android 3. So ART is important to keeping Android quick.

Still, your mileage may vary. Unless you are doing significant computation in your app, a synthetic benchmark will vastly over-emphasize the impact of a better JIT.

Someone benchmarked Dalvik vs ART, and it seems it's already 2x faster, and the performance is much more consistent:


Since this is still probably in alpha mode, I assume it could get even faster with further optimization.

Any explanation of the giant spike for ART? GC misbehaving?

Does anyone have information on what is actually different about ART?

Its a new compiler and VM, written in C++ instead of the Dalvik C, and with a new runtime;

It looks that it can compile to two banckends: one called "Quick" and other called "Portable"

I think "Quick" is a complete home backed Jit, while "Portable" is LLVM based

So probably (im guessing from fast source code study): This VM can JIT from bytecode to native while running (the Quick backend) and can run a already native payload using the LLVM backend..

The native payload probably will be very optimized since is AOT, and the Quick, since is JIT will probably have lower optimizations (as a runtime compiled code)

(and we can assume that, the Dalvik VM is getting obsolete)

Edit: adding more observations..

They have created a very sophisticated retargatable compiler that deliver into a SSA based IR and from there it goes to the backends that i have cited earlier

If it's LLVM, that pretty much opens the door for running Native Client apps on Android, and possibly even merging Android with ChromeOS, right?

Thats a good guess.. theres a way to be sure of it..

The bitcode from Pnacl is different from the LLVM one..

But the "portable" backend naming scheme maybe could mean they will use the PNacl-LLVM instead of the pure LLVM one..

I wonder how Chrome could glue with this.. but if the Nacl/Pnacl uses the PPAPI api, in this hypotethical scenario they would replace the PPAPI runtime with a runtime compatible with ART..

it can be done, and the final c++ application source code would look like the java one..

edit: This could also mean the ndk applications will be first class citizens and wont need to rely on a java shim + native bindings.. I think that is more likely than the ChromeOS integration scenario

"quick" is also an AOT compiler like the LLVM-based "portable", not a JIT.

Ok, so it's AOT.. but this is their own backend? (not the LLVM one?)

and will have no JIT at all?

If they troubled creating their own IR and are not reusing the LLVM one.. it probably means that the LLVM backend are only being used to retarget to the several architectures supported by it..

Otherwise it doesnt make much sense, since they are controlling the optimizing compiler in a custom way without the LLVM help in that matter

Also, if we remember they use renderscript targeting the LLVM and, that the output could go directly to the graphic processors instead of the cpu, it make more sense to have this sort of design..

They work directly in the ABI and voila, everything just works and talk to each other despite its different roots (java, ndk, renderscript.. + ..put something else here..)

If this is indeed the work of Flexycore, there are some explanations here, although they don't go into a lot of details either:


Several have tried to "accelerate" Android, like Myriad with Turbo Dalvik, but it's not so simple. The ART benchmarks are tantalizing, but how much battery life do you give up to get 2X performance in a synthetic benchmark? Hopefully ART is at least as efficient as Dalvik, but nobody outside Google has measured that yet.

Potential improvements in the VM need to show they don't give up in other performance dimensions what they gain in JIT'ed code performance.

Do you have reason to believe that by running code at twice the speed, the energy consumption will be higher?

IMHO this will be absolutely compensated for by being able to switch into a low-power state earlier.

I'd wager Hotspot's JIT would beat the pants off Dalvik's JIT, and make your battery hot while doing it.

Dalvik's JIT is designed unlike other JITs: It is designed to JIT compile less code, but to find the code that has the highest impact. Dalvik's bytecode interpreter already gains what Google has claimed is a 2X improvement over interpreted Java bytecode. Before Android 2.3, that's how Android ran code.

To really run a CPU hot, you need to manually create a workload that utilizes all of the computation units (ALU, FPU, SIMD) interleaving assembler commands. This is nontrivial, and will not happen "by accident" when doing aggressive optimization. Have a look at the cpuburn program for one example.

For a mobile CPU, hot is a lot easier to achieve than on desktop/laptop.

That video is tantalizing, but it's dated 2010. If it works as well as advertised, then why has it taken three years to be part of Android? I'd love to see ART work out though. And the video is almost worth watching just for the very awesome French accent.

G had to do it. Compare Windows Phone 8 to Android - Dual core WP8 phones were better or equal in performance compared to quad core Androids! Had compared Lumia920 with SGS3 few months back.

My pet peeve with Android is drawing apps. I bought a ZTE Open with FirefoxOS, and the first thing that struck me is that the very first drawing app I tried on a low end phone like that totally trounced every (I've tested at least two dozen) drawing app I've tested on my far faster Android phone.

On every single one of them, the brush ends up lagging ridiculously far behind my finger even with quite slow strokes, while on the FirefoxOS phone, I hardly noticed the lag unless I did fast sweeps or used a stylus (there is lag there but usually small enough that if using a finger, my fingertip obscures it)

On Windows Phone 8 everything is native, even .NET code.

So Google does acknowledge that Dalvik's JIT does not cut it.

Pretty much tacit acknowledgement that Dalvik was a huge design mistake.

Funny how Apple got the runtime right in 2007 and now, more than six years later, Google is still struggling with it.

I know you're trolling here but I'm pretty sure Apple has gone through at least two similarly large changes in their toolchain since launching the iPhone. And this isn't the first change Android has had. Over time you figure out better ways to do things.

Actually, the iPhone Obj-C runtime has undergone very little changes since the launch of the iPhone. Apple had already debuted Obj-C 2.0 (which was the most significant change) in OS X 10.5 , before the iPhone launch.

Apple's clang/llvm transition was also already underway, but this had more to do with building more integrated developer tools and not having to deal with gcc, not as much the runtime.

ARC, perhaps the other big new thing you were thinking of, is again just a developer tool that was enabled by the transition to clang. Fundamentally, it is simply the compiler now being smart enough to inject retains/releases automatically when compiling your code instead of you doing it manually. Again, the impact of this is for developers, not end user (runtime) experience.

iOS has been fully native from day one.

Microsoft dropped the JIT model from Windows Phone 7 and moved to fully native starting with Windows Phone 8.

Actually, apple got the runtime right in the 80's :) Objective-C hasn't really changed all that much since then. It really is 'less is more'.

So what is dalvik?

Dalvik is the JVM[1] in Android.

[1] Ignore the pedants saying otherwise; it walks like a duck and quacks like a duck.

If it actually did walk or quack like a duck, you'd be right--but it doesn't. It does not support the Java bytecode format; this is why Groovy, Rhino/LiveConnect, etc. don't work (and you can't do compile-time weaving, further limiting it). It does not support a recognized class library profile.

There is a JVM specification and Dalvik does not conform to it: that means it's not a JVM. It isn't pedantic to say that Dalvik isn't a JVM, because it's not. RoboVM isn't a JVM, either. Supporting Java does not a JVM make.

> this is why Groovy, Rhino/LiveConnect, etc. don't work

You were doing pretty good up to there. The Android toolchain does not compile to Dalvik bytecode. It translates from Java bytecode to Dalvik bytecode. So any language that compiles to Java bytecode could be used to write Android apps.

There are many projects to bring other JVM languages to Android.

I am well aware of how Android's dexer tools work and that non-Java languages work on Dalvik; I use Scala on Android regularly. groovyc builds legal Java bytecode and (as of 2012, at least--since the advent of dexmaker this may have changed) fails when you try to run the dexed output on Android (RTCG). Rhino will work as an embedded runtime on Android with optimizations disabled--in which case it runs in fully interpreted mode--but fails when you enable optimizations or when you attempt to use LiveConnect (runtime class construction).

And this is because Dalvik doesn't understand Java bytecode. It's not conformant to either J2SE or J2ME and these are examples of libraries that puke because of its nonconformance. That's all I'm saying.

I think you are mixing up a couple things here: Converting JVM languages that result in bytecode sequences that dex or Dalvik would never otherwise see in their test suites could uncover bugs. Since all that is open source, and unlikely to rank high on Google's priorities, the answer is to fix those bugs. Unless you mean to say this somehow falls outside Dalvik's coverage of Java semantics.

Other things, like loading Java bytecode dynamically at runtime are limitations of not using Java(TM) bytecode.

Perhaps I'm not being clear. Groovy and Rhino emit bytecode that translates to Java at compile-time. Their runtime code generation facilities crash on Dalvik because Dalvik does not support runtime-generated, JVM-compatible code. Dalvik does not support legal J2SE operations because it doesn't support Java bytecode as per the JVM spec.

I am not saying that Dalvik is bad. I'm saying it isn't a JVM; I was using this as just one example of its not-JVMness.

Was just wondering... for Groovy couldn't they just bundle the tooling to turn the runtime-generated bytecode into Dalvik bytecode? If there were a reliable Dalvik bytecode to JVM bytecode translator I assume most of the issues (similarly occuring with libraries like Javassist etc.) associated with load time and manipilation and code generation could be resolved. Or are there other special limitations on classloading in Android?

> for Groovy couldn't they just bundle the tooling to turn the runtime-generated bytecode into Dalvik bytecode?

There's no "just" when it comes to the Codehaus implementation of the Groovy Language. According to the Codehaus Groovy project manager [1], "Groovy is not able to run properly on Google's Android mobile platform ... (It takes) 20 seconds to start up a simple Hello World".

BTW, that webpage was seeking students to do work making Groovy run on Android, but Google didn't accept that project, or any projects related to Groovy [2], perhaps because no students were interested or maybe because of Codehaus's history of mishandling GSoC projects. The last Groovy project ever accepted was one in 2011 rewriting Groovy's antiquated parser in Antlr 3.0. The project failed and Google only paid out half the project money.

[1] http://groovy.codehaus.org/GSoC+2013

[2] http://www.google-melange.com/gsoc/projects/list/google/gsoc...

Some people will complain that it is not a JVM at all, since it interprets Dalvik bytecode, not Java bytecode. You must run the Android toolchain, which translates Java bytecodes to Dalvik bytecodes, to produce code that runs on Dalvik.

Well, Dalvik is register based and JVM is stack based, this is a big difference

My understanding is pretty limited, so take my explanation with a grain of salt. Dalvik is the virtual machine that runs Android apps, just as the JVM runs Java programs. Android apps are written in Java, compiled to Java bytecode, then converted to Dalvik bytecode.

What a tease!

I can't wait for someone else to invest effort in making this a stable and secure runtime!

With a hostile owner of Java, it seems strategic to begin porting to a new runtime. I'm a little surprised its written in C++ and not go. Every step away from the JVM instruction set and disk formats is a harder case to make for patent/copyright infringement.

Why? Dalvik already is a Google VM that has nothing to do with Sun's/Oracle's implementation (http://en.wikipedia.org/wiki/Dalvik_(software)#Licensing_and...: "Google says that Dalvik is a clean-room implementation rather than a development on top of a standard Java runtime". It also is a register machine, while Java's VM is a stack machine.

I don't expect the runtime to be _written_ in Go, however, when I first saw this title, a little tiny piece of me was hoping it would be a runtime _for_ Go.

So much of Android middleware is written in Java, and uses Android Java's IPC and RPC, a "second runtime" in Android would be a second class citizen.

Android-in-Go, with the middleware in Go, would be a different OS. Maybe a good one, but it would not be Android.

First the Go developers need to overcome a few religious issues, like support for dynamic loading.

From the sound of things, this runtime does much more optimization than the Plan 9-based Go compilers do (it uses SSA), so if speed is the goal (and it looks like it is), Go wouldn't make much sense at this time.

Of course if you write a JIT in Go the performance of the Go compiler is mostly irrelevant.

It's not the performance of the Go compiler that's at issue here, it's the resulting run-time.

Go is still very young. Doesn't make sense to write such a critical piece of software with it quite yet.

Go might be young but the underlying compiler suite is derived from Ken Thompson's c compiler written for plan9 ~25 years ago. Also taking into consideration that the people developing Go have an impressive history of innovation; its not an uncommon by the time somebody actually finishes developing that critical software, for the compilers and runtime to receive vast improvements via new useful diagnostic tools and optimizations.

Google have some pretty critical software running on Go already (and have for a couple of years now). For example, their MySQL scaling proxy[1] is in Go.

[1] https://code.google.com/p/vitess/

But it is very different to use something server-side in your own environment where you can deploy updates easily, vs. client side on devices where the wrong kind of bugs can wreak havoc for millions of uses and make updates to fix them extremely much more complicated.

Yeah, they probably want to wait until Go 2.0 or something, before they commit Android to supporting Go (and support only 64-bit apps while they're at it, since from what I hear Go handles 64-bit much better than 32-bit anyway). So maybe in 2-3 years.

But I do think they should do it eventually, and move away completely from Java, because I think Java is a pain to learn, especially for new programmers who want to make Android apps. Being able to write Go apps for Android could make Android that much more attractive to developers.

In the meantime, this transition to ART apps, will be a huge benefit for users, as their apps will run better, especially on lower-end devices, which KitKat also addresses.

Go isn't a panace either, especially when it comes to dealing with OS-level threads and goroutines.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact