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. Android ART Run me
    A Replacement of Dalvik Run me
    Bob Mingshen Sun
    [email protected]
    October 30, 2014

    View full-size slide

  2. 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

    View full-size slide

  3. 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

    View full-size slide

  4. 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

    View full-size slide

  5. 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

    View full-size slide

  6. 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

    View full-size slide

  7. 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

    View full-size slide

  8. 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

    View full-size slide

  9. 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

    View full-size slide

  10. 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

    View full-size slide

  11. Sequence diagram of compiling
    dex to oat file. (Zoom in)
    Dex2Oat
    CompilerDriver
    ParallelCompilationManager
    CompileMethod
    MIRGraph
    ArmCodeGenerator
    ArmMir2Lir : Mir2Lir
    CompiledMethod

    View full-size slide

  12. 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

    View full-size slide

  13. 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

    View full-size slide

  14. 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

    View full-size slide

  15. 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

    View full-size slide

  16. 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

    View full-size slide

  17. 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

    View full-size slide

  18. OAT File — oatdump
    oatdump: dump oat file to readable text.
    $ oatdump
    Usage: oatdump [options] ...
    --oat -file=
    --image=
    --boot -image=
    --host -prefix
    --output=
    Bob (CUHK) Android ART Runtime October 30, 2014 18 / 45

    View full-size slide

  19. 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

    View full-size slide

  20. 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

    View full-size slide

  21. dex2oat — What’s in the code?
    What does it actually do?
    /art/dex2oat/dex2oat.cc
    UniquePtr 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

    View full-size slide

  22. 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

    View full-size slide

  23. 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

    View full-size slide

  24. 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

    View full-size slide

  25. ART Run me
    Questions
    What’s the internal of ART Runtime?
    Zygote?
    JavaVM?
    Bob (CUHK) Android ART Runtime October 30, 2014 25 / 45

    View full-size slide

  26. 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

    View full-size slide

  27. 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

    View full-size slide

  28. ART Run me — Boo ng
    Look closer...
    jni_invocation.Init(NULL);
    /* FindSymbol(reinterpret_cast (& JNI_GetDefaultJavaVMInitArgs_),
    * "JNI_GetDefaultJavaVMInitArgs ");
    * FindSymbol(reinterpret_cast (& JNI_CreateJavaVM_),
    * "JNI_CreateJavaVM ")
    * FindSymbol(reinterpret_cast (& 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

    View full-size slide

  29. 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

    View full-size slide

  30. 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

    View full-size slide

  31. 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

    View full-size slide

  32. 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

    View full-size slide

  33. 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

    View full-size slide

  34. 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

    View full-size slide

  35. ART Run me — Big Picture
    Bob (CUHK) Android ART Runtime October 30, 2014 35 / 45

    View full-size slide

  36. 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

    View full-size slide

  37. 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

    View full-size slide

  38. ART Run me — Hooking
    How about modifying ART runtime?
    Bob (CUHK) Android ART Runtime October 30, 2014 38 / 45

    View full-size slide

  39. 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

    View full-size slide

  40. 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

    View full-size slide

  41. 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

    View full-size slide

  42. 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

    View full-size slide

  43. 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

    View full-size slide

  44. 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

    View full-size slide

  45. 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

    View full-size slide