MOE under the hood

Hello,

I am currently evaluating some cross-platform technologies.
As JIT is prohibited under iOS there are some tools which AOT compile java source or byte code into machine code.
Now I am trying to understand MOE.
I already found this article, but it doesn’t mention how the code is executed on iOS using ART.

Maybe this is a stupid question, but is ART shipped with the executable to the device and how exactly is the code executed to deal with Apple restrictions? I want to look under the hood but there is less documentation.
My assumption is that the code is converted in a intermediate representation which doesn’t during the execution (otherwise it will break the code signing) and this representation is somehow converted into machine code instruction by the Android runtime.

Hi,

MOE is based on ART in AOT mode. Android also supports this mode, in fact up until Android 7 ART only worked in AOT mode.

The build process looks like this .class -> .dex -> dex2oat (generates native code) -> linking in Xcode.

If you have any more questions just let us know.

Best Regards,
Gergely

Thanks for the fast reply.

Okay that this process .class -> .dex -> dex2oat (generates native code) -> linking in Xcode happens during the build process.
So the result of this process is native machine code and a consequence of this is during runtime the ART isn’t used. ART in the AOT mode is just a tool to produce machine code which i finally executed by the arm processor.

Did I get the point?

Best Regards,
Maximilian

Update, can someone help me?

No, ART is still used on the device.

In general (and this is true for any language that uses a VM), you can think of the structure like this:

  1. You have the VM (aka virtual machine) that provides additional services on top of the operating system (actually in OS theory the OS itself provides a virtual machine on top of the hardware itself, but let’s not overcomplicate things. :slight_smile: )
  2. In most cases the VM provides additional services related to memory management (e.g. garbage collection), threading, and code execution.
  3. Code execution in a VM can happen in many different ways: using an interpreter, using a JIT compiler or using AOT compiled code.
  4. Even if AOT compiled code is used, that code still uses the additional services of the VM, like the garbage collector.

On Android, from Android 5 to Android 6, ART also used AOT. This AOT compilation happened at installation time, directly on the device by the dex2oat utility. Starting with Android 7, Android now uses a mixture of JIT and AOT compilation. This native code is stored in a .oat file for each app on the device. When you launch an app on Android, ART will look for this .oat file, load it into memory, and start running it. That native code however can only work inside ART, because it relies on ART code for memory management, JNI access and so on.

MOE uses the same dex2oat program, but we are running it at build time on the Mac, because we need to link the resulting native code together with the rest of ART into the same iOS app binary - otherwise iOS would not allow its execution.

I hope this helps,
Gergely

So now the ART is more like a runtime library like stdlib and pthreads etc. which provide memory management, threading and many other functions like database on top of the system :laughing:

I believe when most people heard the word VM the first thing comes to their minds is the code execution engine which for android is part of the ART in each devices but for MOE we moved this part to mac.

Thank you guys :slight_smile: that was the answer I was looking for.

Maybe this should be added to the MOE documentation. I think this would help other developer to understand the details of MOE

1 Like

Do I understand correctly that *.oat is treated as Object File during linking?

Is *.oat file is Unix Executable file or Object File or something else?

Hi,

Almost. The OAT file has a custom format, and it basically contains the generated machine code for every Java class in the application. It is linked as a separate Mach-O segment into the final application binary. This (and some memory mapping trickery on startup) is required because the ART version that we currently use generates position dependent code. As we move to a newer ART version from Android P, we will be able to leverage position independent code generated by dex2oat, so we can hopefully retire this custom Mach-O segment and use OAT as if it was a normal object file for static linking, or even separate it into a shared library.

Best Regards,
Gergely