Download - LCU14 100-dalvik is dead long live dalvik

Transcript
Page 1: LCU14 100-dalvik is dead long live dalvik

Dalvik is Dead, Long Live Dalvik! LCU14-September 2014

Stuart Monteith Systems & Software

Page 2: LCU14 100-dalvik is dead long live dalvik

▪What is Dalvik™? ▪Porting Dalvik onto AArch64 ▪ART ▪Working on AOSP1 ▪Q&A

2

Outline

1 - Android™ Open Source Project

Page 3: LCU14 100-dalvik is dead long live dalvik

What is Dalvik™?

3

?

Page 4: LCU14 100-dalvik is dead long live dalvik

Android™ & Dalvik™

4

Applications

Application Framework

Libraries

Kernel

Android™ Runtime

Core Libraries

Dalvik VM

Bionic

SSL

Page 5: LCU14 100-dalvik is dead long live dalvik

▪ Dalvik is a virtual machine ▪ A managed runtime ▪ Interpreter ▪ Executes Java™ class files translated into

Dalvik “dex” bytecode ▪ Exception handling ▪ Object oriented ▪ References rather than pointers ▪ Garbage collection ▪ Concurrency ▪ Platform independence

What is Dalvik™?

5

Interpreter

Heap

Native Code OS

Bytecode

Page 6: LCU14 100-dalvik is dead long live dalvik

Compiling for Dalvik

6

*.java

*.class

*.dex *.apk *.odex

dx

javac

dexopt

InstallationDevelopment

/data/dalvik-cache/

Page 7: LCU14 100-dalvik is dead long live dalvik

Devices

7

Relative to Phone in 2008

0

7.5

15

22.5

30

CPU RAM Pixels

Phone `08 Phone `14 Tablet `10 Tablet `14

Page 8: LCU14 100-dalvik is dead long live dalvik

▪ Just-In-Time (JIT) Compiler - Android™ 2.2 “Froyo”, May 2010 ▪ Concurrent Garbage collection - Android 2.3 “Gingerbread”, December 2010 ▪ SMP1 support - Android 3.0 “Honeycomb”, February 2011

Dalvik Evolution

81 - Symmetric MultiProcessing

Page 9: LCU14 100-dalvik is dead long live dalvik

▪ Just-In-Time Compiler ▪ Compiles code at runtime ▪ Only code that is executed is compiled ▪ Only “Hot code” is compiled

▪ Interpreter executes bytecode instruction by instruction ▪ Profiles code ▪ Sends linear sequences of code to JIT ▪ Native code branched to from interpreter

▪ However… ▪ Code produced is not ideal

▪ Still, 5x faster than interpreter alone

Tracing JIT

9

Page 10: LCU14 100-dalvik is dead long live dalvik

Traces

10

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

Page 11: LCU14 100-dalvik is dead long live dalvik

Traces

11

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

0000: const-wide/16 v0, 0 0002: const/4 v2, #int 0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d

Page 12: LCU14 100-dalvik is dead long live dalvik

Traces

12

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7! : : : : : :!0017: const-wide/high16 v7, #long!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!

Page 13: LCU14 100-dalvik is dead long live dalvik

0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025!0005: if-ge v6, v13, 001d

Traces

13

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

Page 14: LCU14 100-dalvik is dead long live dalvik

Traces

14

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

07:!T0!

1b:

Page 15: LCU14 100-dalvik is dead long live dalvik

Traces

15

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

07:!T0!

1b:

26:!T1!

05:

1d:

1d:

Page 16: LCU14 100-dalvik is dead long live dalvik

Traces

16

0000: const-wide/16 v0, #int 0 // #0!0002: const/4 v2, #int 0 // #0!0003: move v6, v2!0004: move-wide v2, v0!0005: if-ge v6, v13, 001d // +0018!0007: mul-double v4, v2, v2!0009: mul-double v7, v0, v0!000b: sub-double/2addr v4, v7!000c: add-double/2addr v4, v9!000d: const-wide/high16 v7, #long 4611686018427387904 // #4000!000f: mul-double/2addr v2, v7!0010: mul-double/2addr v0, v2!0011: add-double/2addr v0, v11!0012: mul-double v2, v4, v4!0014: mul-double v7, v0, v0!0016: add-double/2addr v2, v7!0017: const-wide/high16 v7, #long 4616189618054758400 // #4010!0019: cmpl-double v2, v2, v7!001b: if-lez v2, 0026 // +000b!001d: sget v0, LMandle;.threshold:I // field@0001!001f: int-to-double v0, v0!0020: int-to-double v2, v13!0021: div-double/2addr v0, v2!0022: int-to-double v2, v6!0023: mul-double/2addr v0, v2!0024: double-to-int v0, v0!0025: return v0!0026: add-int/lit8 v2, v6, #int 1 // #01!0028: move v6, v2!0029: move-wide v2, v4!002a: goto 0005 // -0025

07:!T0!

1b:

26:!T1!

05:

1d:!T2!

25:

00:!T3!

05:

Page 17: LCU14 100-dalvik is dead long live dalvik

17

Garbage CollectionThread!Stack

A

B

C

D

E

F

Page 18: LCU14 100-dalvik is dead long live dalvik

18

Garbage Collection (Mark)Thread!Stack

A

B

C

D

E

F

Page 19: LCU14 100-dalvik is dead long live dalvik

19

Garbage Collection (Sweep)Thread!Stack

A

B

C

D

E

F

XX

Page 20: LCU14 100-dalvik is dead long live dalvik

Porting Dalvik™ onto AArch64

20

Page 21: LCU14 100-dalvik is dead long live dalvik

▪ Model, kernel, bionic and shell below ▪ LCU14-411 From zero to booting Nano-Android

▪ Not just a recompile! ▪ Dalvik™ VM implementation

▪ Portable C interpreter, garbage collection, class loading, JNI ▪ Compressed references

▪ Java™ core libraries - platform/libcore: ▪ java.* classes ▪ int always 32-bit, long always 64-bit ▪ Java: int pointer; ➤ long pointer;!▪ C: jint pointer; ➤ jlong pointer;!▪ pointer = (jlong)(void*) nativeStructure;!

▪ Build system21

ARM’s AArch64 Porting effort

Page 22: LCU14 100-dalvik is dead long live dalvik

▪ Then: ▪ AArch64 assembler interpreter

▪ Slightly before with VIXL ▪ VIXL - library for simulating, assembling and disassembling ARMv8 A64

instructions. ▪ Just-In-Time compiler ▪ The rest of the Android™libraries

▪ End result - Android with only 64-bit binaries ▪ Initially 64-bit Dalvik™ running on host in November 2012 ▪ On ARM’s ARMv8 models on command line in February 2013 ▪ Then AOSP on models from July 2013

22

ARM’s AArch64 Porting effort (2)

Page 23: LCU14 100-dalvik is dead long live dalvik

▪ After porting AOSP to AArch64 - ART came along in October 2013 ▪ Not all was lost:

▪ Able to boot AOSP from July 2013 (4.2/4.3) through to 4.4 on Dalvik™ for AArch64

▪ Demonstrated AOSP on Juno 2014

Dalvik is Dead, Long Live ART!

23

Page 24: LCU14 100-dalvik is dead long live dalvik

ART - Android™ Runtime

24

Page 25: LCU14 100-dalvik is dead long live dalvik

▪ Introduced October 2013 as experimental runtime in Android™ 4.4 “KitKat” ▪ First release in Android “L” ▪ Less lag, more performance ▪ Productised through 2014 ▪ ART also introduces 64-bit support into Android

▪ ARM contributed compiler backend components from Dalvik for AArch64 ▪ + JNI compiler, glue, fixes, performance features/tweaks

ART

25

Page 26: LCU14 100-dalvik is dead long live dalvik

▪ Dalvik™ Virtual Machine ▪ Java™ applications as before ▪ Garbage collection, class loading, object references, all as before ▪ It is not translating programs into C/C++

▪ Native code works as before (Java Native Interface - JNI) ▪ Eclipse + ADT or Android Studio, NDK are essentially unchanged

▪ Targeting the same platform - Android ▪ Debugging ▪ dalvikvm!▪ Zygote

▪ app_process - Android’s command for starting VMs.

Unchanged

26

Page 27: LCU14 100-dalvik is dead long live dalvik

Changed▪ Garbage collection + allocation

▪ Parallel, less pauses ▪ C++ Interpreter ▪ Ahead-of-time compilation (AOT) ▪ Support for 64-bit execution ▪ Diagnostics ▪ Stricter JNI ▪ Stricter bytecode verification

27

Page 28: LCU14 100-dalvik is dead long live dalvik

▪ No JITing during startup ▪ Compilation time spent at installation

▪ boot.art: ▪ Part of the heap stored on flash ▪ Built as part of firmware image ▪ Pre-initialized VM heap ▪ ~12 MB on AOSP

▪ Zygote as before ▪ Initialize ▪ Wait for binder request to fork new apps

Initialization

28

Page 29: LCU14 100-dalvik is dead long live dalvik

▪ Stacks now unified - each thread has one stack each ▪ Original Dalvik™ implementation had separately allocated VM stack ▪ ART has VM, interpreted, compiler and JNI frames all on same stack ▪ Stack characteristics may be different

▪ Stack overflow + null pointer exceptions detected through fault handlers ▪ Trap and handle

▪ Thread local allocation ▪ Threads can allocate objects without getting global heap lock

Threads

29

Page 30: LCU14 100-dalvik is dead long live dalvik

▪ More pluggable ▪ Provisions in runtime for different GC schemes

▪ Parallel & Concurrent ▪ More threads doing the work

▪ Background collection ▪ More throughput, less responsive

▪ Mark & Sweep, semi-space, large objects, variations

Garbage Collection

30

Page 31: LCU14 100-dalvik is dead long live dalvik

▪ Two Zygotes, one 32-bit , one 64-bit ▪ 64-bit is the default ▪ Files duplicated on flash - 32/64-bit. ▪ Compressed references

▪ 32-bit object references ▪ Mapped within bottom 4 GB of memory ▪ Heap size: 256 MB

▪ Hard-float ABI ▪ Parameters passed in floating-point registers

▪ JNI 64-bit libraries ▪ Apps with 32-bit JNI run by 32-bit Zygote

64-bit Support

31

Zygote32 Zygote64

32 bit App 64 bit App64-bit App32-bit App

fork()

Page 32: LCU14 100-dalvik is dead long live dalvik

Compiling for ART

32

*.java

*.class

*.dex *.apk *.odex

dx

javac

dex2oat

InstallationDevelopment

/data/dalvik-cache/arm!or!

/data/dalvik-cache/arm64

Page 33: LCU14 100-dalvik is dead long live dalvik

▪ Compiler driver ▪ Portable compiler ▪ Sea of nodes IR ▪ Quick compiler ▪ Optimising compiler

▪ More platform independent code ▪ ARM, MIPS & x86 with 64-bit variants

▪ Performed at install time ▪ Compiler compiles with multiple threads in parallel ▪ Good code quality without onerous compile time

Compilation

33

Page 34: LCU14 100-dalvik is dead long live dalvik

Working on AOSP

34

Page 35: LCU14 100-dalvik is dead long live dalvik

▪ Google working in the open with ART in AOSP ▪ ARM, MIPS, Intel & ARM partners contribute ▪ 64-bit porting work has been a proving ground for this approach

▪ Ideas are nice, but code is better ▪ Understand who is doing what

▪ Check, post to the Google groups (see android-platform, etc.) ▪ Important to test on more than just ARM platforms - check MIPS & x86 ▪ Frequently unstable: reversions, build system restructuring

▪ Android is big, and components have interdependencies

Working on AOSP

35

Page 36: LCU14 100-dalvik is dead long live dalvik

▪ AOSP’s gerrit has useful features ▪ Use it to track new changes in projects through email ▪ Volume can be high - can filter on git fields ▪ esp. if you are working on a particular feature

▪ Keep a working branch - pull it forward as quickly as possible though ▪ Use and add to the unit tests

▪ art # mma test-art

Working on AOSP

36

Page 37: LCU14 100-dalvik is dead long live dalvik

Thank You

The trademarks featured in this presentation are registered and/or unregistered trademarks of ARM Limited (or its subsidiaries) in the EU and/or elsewhere. All rights reserved. Any other marks featured may be trademarks of their

respective owners

37

Page 38: LCU14 100-dalvik is dead long live dalvik

▪ Today: ▪ LCU14-104: Everything’s Done! Android™ for 64-bit ARMv8, What’s next?

◦ Next in this room ▪ LCU14-108: Panel: Faster, Better and more Open AOSP Support

◦ 12:10, this room ▪ Wednesday:

▪ LCU14-309: Introducing Android NDK for 64bit ARMv8 SOCs ◦ 12:10 Grand Peninsula A

▪ Thursday: ▪ LCU14-411: From zero to booting Nano-Android with 64bit support

◦ 12:10 Grand Peninsula C ▪ Friday

▪ LCU14-502: Android User-Space Tests: Multimedia codec tests, Status and Open Discussions ◦ 09:15 Grand Peninsula B

Sessions

38

Page 39: LCU14 100-dalvik is dead long live dalvik

▪ Introducing ART: https://source.android.com/devices/tech/dalvik/art.html ▪ ART compatibility: https://developer.android.com/guide/practices/verifying-apps-art.html ▪ Google I/O 2014, The ART Runtime: https://www.youtube.com/watch?v=EBlTzQsUoOw ▪ VIXL: https://github.com/armvixl/vixl ▪ ARM Juno: http://www.arm.com/products/tools/development-boards/versatile-express/

juno-arm-development-platform.php ▪ AOSP Gerrit: https://android-review.googlesource.com/ ▪ Linaro's Android team: https://wiki.linaro.org/Platform/Android ▪ Bug Reports: https://source.android.com/source/report-bugs.html ▪ ARM Connected Community: http://community.arm.com/groups/android-community ▪ ARMv8 Reference Manual: http://infocenter.arm.com/help/index.jsp?topic=/

com.arm.doc.ddi0487a.c/index.html

39

References

Page 40: LCU14 100-dalvik is dead long live dalvik

!▪ The Android™ robot is reproduced or modified from work created and shared by Google and

used according to terms described in the Creative Commons 3.0 Attribution License.

Notices

40

Page 41: LCU14 100-dalvik is dead long live dalvik

Backup slides

41

Page 42: LCU14 100-dalvik is dead long live dalvik

42

CONFIDENTIAL 6

Multi-lib: A 64bit 'primary' boot