Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android ART Runtime: A Replacement of Dalvik Runtime

Android ART Runtime: A Replacement of Dalvik Runtime

Mingshen Sun

October 30, 2014
Tweet

More Decks by Mingshen Sun

Other Decks in Technology

Transcript

  1. Outline 1 Background Dalvik & ART APK Building Process 2

    LLVM What is LLVM? How does ART utilize LLVM? 3 OAT File OAT File Structure oatdump 4 dex2oat Overview What’s in the code? Workflow boot.art & boot.oat 5 ART Runtime Booting ClassLinker Big Picture Hooking Experiment 6 DVM vs ART Benchmarks 7 Conclusion Bob (CUHK) Android ART Runtime October 30, 2014 2 / 45
  2. Background ART is a new Android runtime being introduced experimentally

    in the 4.4 release. This is a preview of work in progress in KitKat that can be turned on in Settings > developer options. This is available for the purpose of obtaining early developer and partner feedback. —Android Developers Bob (CUHK) Android ART Runtime October 30, 2014 3 / 45
  3. Background — Dalvik & ART Dalvik Virtual Machine: a register

    based Java virtual machine. ART Runtime? LLVM? Ahead-of-Time (AOT)? dex2oat? performance? Bob (CUHK) Android ART Runtime October 30, 2014 4 / 45
  4. Background — APK Building Process Dalvik Runtime *.java --- javac

    --> *.class --- dx --> classes.dex --- dexopt ---> *.odex classes.dex: Dalvik executable file. (bytecode for DVM) ART Runtime classes.dex --- dex2oat ---> *.oat *.oat? *.oat file is in /data/dalvik-cache/ directory. File extension is still *.dex. $ file system@[email protected]@classes.dex system@[email protected]@classes.dex: ELF 32-bit LSB shared object , ARM , EABI5 version 1 (GNU/Linux), dynamically linked , stripped Bob (CUHK) Android ART Runtime October 30, 2014 5 / 45
  5. Background Dalvik Virtual Machine Just-in-Time (JIT) compilation: aka dynamic translation,

    is compilation done by VM during execution of a program — at run time — rather than prior to execution. Cross-platform. ART utilizes LLVM to compile the bytecode. Ahead-of-Time (AOT) compilation to native code. AOT transforms the bytecode of an existing virtual machine into machine code. AOT compilers can perform complex and advanced code optimizations. Bob (CUHK) Android ART Runtime October 30, 2014 6 / 45
  6. How LLVM Works? — What is LLVM? The LLVM Project

    is a collection of modular and reusable compiler and toolchain technologies. Frontend: responsible for parsing, validating and diagnosing errors in the input code, then translating the parsed code into LLVM IR. LLVM IR (Intermediate Representation): the form it uses to represent code in the compiler. LLVM Optimizer: a series of analysis and optimization passes which improve the code. Backend: produce native machine code for different platform. [4] Bob (CUHK) Android ART Runtime October 30, 2014 7 / 45
  7. LLVM — What is LLVM? Modular Design Choosing when and

    where each phase runs. Unit testing and optimizer. [4] Bob (CUHK) Android ART Runtime October 30, 2014 8 / 45
  8. LLVM — How does ART u lize LLVM? art git

    :(21 b2216) $ tree -L 1 . |-- Android.mk |-- build |-- compiler |-- dalvikvm |-- dex2oat |-- jdwpspy |-- MODULE_LICENSE_APACHE2 |-- NOTICE |-- oatdump |-- runtime |-- test `-- tools Key modules: compiler: an oat compiler based on LLVM dex2oat: convert (compile) dex file to oat file runtime: ART runtime for oat file in Android Bob (CUHK) Android ART Runtime October 30, 2014 9 / 45
  9. LLVM — How does ART u lize LLVM? Basic flow

    of ART compiler 1 extract class/method in dex file: /art/compiler/dex/frontend.cc 2 compile method into middle level IR: /art/compiler/dex/frontend.cc 3 optimize IR: /art/compiler/dex/mir_optimization.cc 4 compile middle level into low level IR for ARM/x86/MIPS platform: /art/compiler/dex/mir_optimization.cc 5 generate ARM machine code: /art/compiler/llvm/compiler_llvm.cc 6 write/strip into oat file (ELF file): /art/compiler/elf_writer.cc Bob (CUHK) Android ART Runtime October 30, 2014 10 / 45
  10. Sequence diagram of compiling dex to oat file. (Zoom in)

    Dex2Oat CompilerDriver ParallelCompilationManager CompileMethod MIRGraph ArmCodeGenerator ArmMir2Lir : Mir2Lir CompiledMethod
  11. OAT File Actually an OAT file is an ELF file.

    not an executable file. seems like a shared object (library). should be linked/executed in ART Runtime. Bob (CUHK) Android ART Runtime October 30, 2014 12 / 45
  12. OAT File — Overview of ELF File +----------------------+ | ELF

    Header | +----------------------+ | Program Header Table | +----------------------+ | Text segment | +----------------------+ | Data segment | +----------------------+ | BSS segment | +----------------------+ | ". symtab" section | +----------------------+ | ". strtab" section | +----------------------+ | ". shstrtab" section | +----------------------+ | Debug sections | +----------------------+ | Section Header Table | +----------------------+ Note that the actual ordering of the file may be different from that shown, since only an ELF header has a fixed position in the file. All other parts of the file have a position defined by: the ELF header, the Program Header Table, item the Section Header Table. Sections .symtab: symbol table (e.g., function name and address) .strtab: string table (e.g., strings in the code) .shstrtab: string table of section names Segments Text: the code for the executable Data: initialized read-write data BSS: uninitialized data Bob (CUHK) Android ART Runtime October 30, 2014 13 / 45
  13. OAT File — OAT File Structure +-----------------------+ | ELF Header

    | +-----------------------+ | Program Header Table | +-----------------------+ | .dynsym Section | | ELF32_Sym STN_UNDEF | | ELF32_Sym oatdata | | ELF32_Sym oatexec | | ELF32_Sym oatlastword | +-----------------------+ | .dynstr Section | | \0 | | oatdata \0 | | oatexec \0 | | oatlastword \0 | +-----------------------+ | .hash Section | +-----------------------+ | .rodata | | oatdata ..oatexec -4 | +-----------------------+ | .text | | oatexec .. oatlastword | +-----------------------+ | .dynamic | +-----------------------+ | .shstrtab | +-----------------------+ | Section Header Table | +-----------------------+ Important section: .dynsym: three pointer (oatdata, oatexec, oatlastword) .dynstr .rodata (from oatdata to oatexec-4) .text (from oatexec to oatlastword) Load oat file? dlopen("*.oat") dlsym("oatdata"), dlsym("oatexec"), dlsym("oatlastword") Bob (CUHK) Android ART Runtime October 30, 2014 14 / 45
  14. OAT File — OAT File Structure What’s in the header?

    $ readelf -h system@[email protected]@classes.dex readelf: Error: Unable to read in 0x28 bytes of section headers ELF Header: Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement , little endian Version: 1 (current) OS/ABI: UNIX - GNU ABI Version: 0 Type: DYN (Shared object file) Machine: ARM Version: 0x1 Entry point address: 0x0 Start of program headers: 52 (bytes into file) Start of section headers: 10014832 (bytes into file) Flags: 0x5000000 , Version5 EABI Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 5 Size of section headers: 40 (bytes) Number of section headers: 8 Section header string table index: 7 readelf: Error: Unable to read in 0x140 bytes of section headers readelf: Error: Unable to read in 0x38 bytes of dynamic section Type: DYN/EXE Entry point address? Noting useful. Bob (CUHK) Android ART Runtime October 30, 2014 15 / 45
  15. OAT File — OAT File Structure What are the symbols?

    $ readelf -s system@[email protected] Symbol table '.dynsym ' contains 4 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 60 ac9000 0x1902000 OBJECT GLOBAL DEFAULT 4 oatdata 2: 623 cb000 0x22f9660 OBJECT GLOBAL DEFAULT 5 oatexec 3: 646 c465c 4 OBJECT GLOBAL DEFAULT 5 oatlastword Bob (CUHK) Android ART Runtime October 30, 2014 16 / 45
  16. OAT File — .rodata (oatdata..oatexec-4) image_file_location: boot.oat Table: class table

    Code: instructions (machine code) for different platforms. CodeDexFiles: some pointers (mapping_table, vmap_table, etc.) to the original dex file. +------------------------------+ | .rodata (oatdata ..oatexec -4) | | OatHeader | | image_file_location | | Table (OatDexFile , OatClass) | +------------------------------+ | .text (oatexec .. oatlastword) | | Code (instructions) | | CodeDexFiles ( | | mapping_table , | | vmap_table , | | gc_map) | +------------------------------+ Bob (CUHK) Android ART Runtime October 30, 2014 17 / 45
  17. OAT File — oatdump oatdump: dump oat file to readable

    text. $ oatdump Usage: oatdump [options] ... --oat -file=<file.oat > --image=<file.art > --boot -image=<file.art > --host -prefix --output=<file > Bob (CUHK) Android ART Runtime October 30, 2014 18 / 45
  18. OAT File — oatdump Output information: MAGIC: ... CHECKSUM: ...

    INSTRUCTION SET: ... DEX FILE COUNT: ... ... IMAGE FILE LOCATION: /data/dalvik -cache/system@[email protected] ... OAT DEX FILE: location: /system/app/Calculator.apk checksum: 0x81887450 [class name] [method name] DEX CODE: ... OAT DATA: ... CODE: 0x40426004: f8d9c010 ldr.w r12 , [r9 , #16] ; stack_end_ 0x40426008: e92d4060 push {r5, r6 , lr} ... image file oat dex file Bob (CUHK) Android ART Runtime October 30, 2014 19 / 45
  19. dex2oat — Overview dex2oat is a tool to convert (compile)

    dex file to oat file (ELF file). Usage: dex2oat [options ]... --dex -file=: specifies a .dex file to compile. --oat -file=: specifies the oat output destination via a filename. --boot -image =: provide the image file for the boot class path. --compiler -backend =( Quick|QuickGBC|Portable ): select compiler backend ... Bob (CUHK) Android ART Runtime October 30, 2014 20 / 45
  20. dex2oat — What’s in the code? What does it actually

    do? /art/dex2oat/dex2oat.cc UniquePtr <CompilerDriver > driver( new CompilerDriver(compiler_backend_ , // quick|portable instruction_set_ , // arm/x86/mips image , // boot.art image_classes.release(), thread_count_ , dump_stats) ); driver ->CompileAll(class_loader , dex_files , timings ); Bob (CUHK) Android ART Runtime October 30, 2014 21 / 45
  21. dex2oat — Workflow boot.oat & boot.art dex2oat will compile all

    the framework library into boot.oat file in the first boot time. framework library: framework.jar, service.jar, webviewchromium.jar ... boot.oat is like dynamic load library in every app process. difference between boot.oat & boot.art? shell@i9100 :/data/dalvik -cache # ps | grep zygote root 1852 1 232548 40488 ffffffff 400687 fc S zygote shell@i9100 :/data/dalvik -cache # cat /proc /1852/ maps | grep boot 40245000 -40246000 r--p 00000000 103:02 106605 /data/dalvik -cache/system@[email protected] 41697000 -416 c3000 r--p 00 ac8000 103:02 106606 /data/dalvik -cache/system@[email protected] 60000000 -60 ac8000 rw-p 00000000 103:02 106606 /data/dalvik -cache/system@[email protected] 60ac8000 -623 cb000 r--p 00000000 103:02 106605 /data/dalvik -cache/system@[email protected] 623cb000 -646 c5000 r-xp 01903000 103:02 106605 /data/dalvik -cache/system@[email protected] 646c5000 -646 c6000 rw-p 03 bfd000 103:02 106605 /data/dalvik -cache/system@[email protected] Bob (CUHK) Android ART Runtime October 30, 2014 22 / 45
  22. dex2oat — boot.oat & boot.art boot.art contains metadata information (objects,

    methods) pointing to boot.oat which contains machine code. memory layout image: loaded at an absolute address and contains Objects with absolute pointers within the image. image: absolute pointers from Methods in the image to their code in the oat. boot.oat: absolute pointers from the code in the oat to Methods. boot.oat: absolute pointers from code in the oat to other code. +--------------+ | image | | Objects | | Methods |<-| +--------------+ | | boot oat | | | Method 1 Code|<-| | Method 2 Code|<-| +--------------+ | alloc spaces | <--- Heap +--------------+ Bob (CUHK) Android ART Runtime October 30, 2014 23 / 45
  23. dex2oat — Workflow Existing apps & new installed apps. 1

    scanDirLI() method of PackageManagerService (PKMS) will monitor /data/data/ directory. 2 In installation time, PKMS will copy apk file into /data/data/ directory. 3 PKMS will check whether to optimize this apk file. 4 PKMS will send command to installd daemon through socket to optimize this app. 5 installd will check current runtime (Dalvik or ART) and then perform dexopt (dexpot for Dalvik and dex2oat for ART). Bob (CUHK) Android ART Runtime October 30, 2014 24 / 45
  24. ART Run me Questions What’s the internal of ART Runtime?

    Zygote? JavaVM? Bob (CUHK) Android ART Runtime October 30, 2014 25 / 45
  25. ART Run me — Boo ng Init Zygote /frameworks/base/cmds/app_process/app_main.cpp if

    (zygote) { runtime.start ("com.android.internal.os.ZygoteInit", startSystemServer ? "start -system -server" : ""); } Bob (CUHK) Android ART Runtime October 30, 2014 26 / 45
  26. ART Run me — Boo ng runtime? class AppRuntime :

    public AndroidRuntime runtime.start()? /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; startVm (&mJavaVM , &env); jclass startClass = env ->FindClass(slashClassName ); jmethodID startMeth = env ->GetStaticMethodID(startClass , "main", "([ Ljava/lang/String ;)V"); env ->CallStaticVoidMethod(startClass , startMeth , strArray ); Bob (CUHK) Android ART Runtime October 30, 2014 27 / 45
  27. ART Run me — Boo ng Look closer... jni_invocation.Init(NULL); /*

    FindSymbol(reinterpret_cast <void **>(& JNI_GetDefaultJavaVMInitArgs_), * "JNI_GetDefaultJavaVMInitArgs "); * FindSymbol(reinterpret_cast <void **>(& JNI_CreateJavaVM_), * "JNI_CreateJavaVM ") * FindSymbol(reinterpret_cast <void **>(& JNI_GetCreatedJavaVMs_), * "JNI_GetCreatedJavaVMs ") */ startVm (&mJavaVM , &env) /* 1. Setting Java VM parameters (which I think is useless for ART) * 2. JNI_CreateJavaVM(pJavaVM , pEnv , &initArgs) */ Bob (CUHK) Android ART Runtime October 30, 2014 28 / 45
  28. ART Run me — Boo ng JNI_CreateJavaVM /art/runtime/jni_internal.cc extern "C"

    jint JNI_CreateJavaVM(JavaVM ** p_vm , JNIEnv ** p_env , void* vm_args) { Runtime* runtime = Runtime :: Current (); bool started = runtime ->Start (); *p_env = Thread :: Current()->GetJniEnv (); *p_vm = runtime ->GetJavaVM (); } Bob (CUHK) Android ART Runtime October 30, 2014 29 / 45
  29. ART Run me — Global Instance Remember gDvm in Dalvik

    VM? DvmGlobals gDvm; gDvm->loadedClasses; ART Runtime* runtime. Single instance. ART runtime is not a Virtual Machine. It seems like a JavaVM proxy (interface) for compatibility. Bob (CUHK) Android ART Runtime October 30, 2014 30 / 45
  30. ART Run me — ClassLinker ClassLinker is also an important

    single instance member in ART Runtime* runtime. It is responsible for: finding class pointers FindClass() LookupClass() loading classes/methods/field LoadClass() LoadField() LoadMethod() linking classes/fields/methods LinkClass() LinkMethods() LinkVirtualMethods() registering/verifying/resolving classes/methods/fields Bob (CUHK) Android ART Runtime October 30, 2014 31 / 45
  31. ART Run me — ClassLinker Other useful methods: NumLoadedClasses: get

    the number of loaded classes VisitClasses(): visit every class using a user-defined visitor() function Help classes: Class/Method/Field mirror: /art/runtime/mirror/ Class ArtMethod ArtField Bob (CUHK) Android ART Runtime October 30, 2014 32 / 45
  32. ART Run me — Reconstruct Our Knowledge In the view

    of runtime memory: Zygote boot.art: class table for machine code in boot.oat boot.oat: pre-compiled machine code for Android SDK app.oat: compiled application oat file Bob (CUHK) Android ART Runtime October 30, 2014 33 / 45
  33. ART Run me — Reconstruct Our Knowledge In the view

    of ART runtime: ClassLinker: classes/methods/fields manage class_table: pointers to each class Class: class mirror ArtMethod: method mirror class Code: ARM/MIPS/X86 instructions JavaVM: a proxy to use JNI call .so file Bob (CUHK) Android ART Runtime October 30, 2014 34 / 45
  34. ART Run me — Big Picture Bob (CUHK) Android ART

    Runtime October 30, 2014 35 / 45
  35. ART Run me — Hooking Hooking in ART Runtime could

    be totally different. manipulate oat file? operate ART runtime? Bob (CUHK) Android ART Runtime October 30, 2014 36 / 45
  36. ART Run me — Hooking oat file: absolute address pointing

    to boot.art modify code section? checksum? hardcode address? Bob (CUHK) Android ART Runtime October 30, 2014 37 / 45
  37. ART Run me — Hooking How about modifying ART runtime?

    Bob (CUHK) Android ART Runtime October 30, 2014 38 / 45
  38. ART Run me — Hooking vtable? virtual method table, dispatch

    table basically an array of pointers to (virtual) methods will be set to point to the right function at runtime Bob (CUHK) Android ART Runtime October 30, 2014 39 / 45
  39. ART Run me — Experiment Quick and dirty experiment: HelloPrinter

    hp = new HelloPrinter (); // Load and initalize HelloPrinter class WorldPrinter wp = new WorldPrinter (); // Load and initalize WorldPrinter class hp.print (); // Print "Hello" to the log NativeUtil.hook (); // Call native hook function in libhookart.so hp.print (); // "Hello" or "World" in the log? Objective: inject (load) an .so file in the memory modify the print() method pointer in the vtable of HelloPrinter change from HelloPrinter.print() to WorldPrinter.print() Expected result: first ”Hello” in the log then ”World” Bob (CUHK) Android ART Runtime October 30, 2014 40 / 45
  40. ART Run me — Experiment Result in the logcat: $

    adb shell logcat -s "hookart" D/hookart (12730): Hello D/hookart (12730): [+] NativeUtil_hook <--- Enter libhookart.so and execute hook() D/hookart (12730): [+] runtime: 0x1734028 D/hookart (12730): [+] classLinker: 0x17454e0 D/hookart (12730): [+] Found HelloPrinter Class: 0x64873f08 D/hookart (12730): [+] Found WordPrinter Class: 0x648743e0 D/hookart (12730): [+] Starting change method D/hookart (12730): [+] helloPrinterClass: NumDirectMethods 1, NumVirtualMethods 1 D/hookart (12730): [+] worldPrinterClass: NumDirectMethods 1, NumVirtualMethods 1 D/hookart (12730): [+] CompiledCode m1: 0x474c2e25 , m2: 0x474c318d <--- D/hookart (12730): [+] Successful! m1: 0x474c318d , m2: 0x474c318d <--- D/hookart (12730): World Bob (CUHK) Android ART Runtime October 30, 2014 41 / 45
  41. DVM vs ART — Benchmarks Benchmarks by AndroidPolice [1]. Table:

    Linpack for Android Dalvik ART Single Thread 135 149 10.93% Multi-Thread 336 383 13.82% Table: Real Pi Dalvik ART AGM+FFT Formula (2,000,000 digits) 21.48 20.76 3.49% Machin’s Formula (10,000 digits) 51.39 46.01 11.69% Bob (CUHK) Android ART Runtime October 30, 2014 42 / 45
  42. DVM vs ART — Benchmarks Benchmarks by AndroidPolice [1]. Table:

    Quadrant Standard Dalvik ART Quadrant Standard 8,435 11,980 42.03% CPU 19,751 38,548 95.17% Mem 13,371 12,269 -8.24% I/O 6,556 6,612 0.85% 2D 301 301 0.00% 3D 2,196 2,172 -1.09% Bob (CUHK) Android ART Runtime October 30, 2014 43 / 45
  43. Conclusion Covers: Dalvik & ART LLVM OAT File dex2oat ART

    Runtime (booting, hooking) DVM vs ART ART is still an experimental runtime in Android system. There are still some uncompleted logics. But we believe that ART Runtime will finally replace Dalvik Runtime in the future due to better performance. Bob (CUHK) Android ART Runtime October 30, 2014 44 / 45
  44. References AndroidPolice. Meet ART, Part 2: Benchmarks - Performance Won’t

    Blow You Away Today, But It Will Get Better. http://www.androidpolice.com/2013/11/12/meet-art- part-2-benchmarks-performance-wont-blow-away-today-will-get-better/. AndroidXref. http://androidxref.com/4.4_r1/. Google. Android Open Source Project. Chris Lattner. The Architecture of Open Source Applications. Bob (CUHK) Android ART Runtime October 30, 2014 45 / 45