Android Runtime(ART)編譯過程與所謂suspend-points

”ART’s Quick Compiler:an unofficial overview“

Matteo Franchin     LCA15, February 2015

看了這個關於ART的PPT,記錄一下。


ART編譯器有兩種一種叫做Portable(後端好像是llvm),還一種就是常用quick,下文介紹基於quick。  

ART不僅僅編譯執行,也會解釋執行(跟dalvik基本上一樣把)

Java method is the compilation unit for the Quick Compiler.

Quick編譯器的編譯單元是一個java方法

dalvikvm64 calls the compiler, dex2oat, to generate OAT file in /data/dalvik-cache/arm64.

64位虛擬機調用編譯 dex2oat方法 來生成一個oat文件,保存在/data/dalvik-cache/arm64目錄下

dex2oat uses several threads to compile all the methods.


DEX bytecode:

register-based variable length instructions (≥ 2 bytes).

dex指令是基於寄存器的,可變長度的(>2字節,16位或32位)
32-bit, untyped virtual registers (vregs): v0-v65535.

dex文件使用的是32位的虛擬寄存器V0-V65535 與機器碼使用的Rx物理寄存器不同
64-bit values stored in consecutive pairs of registers.

64位的值存儲於2個相鄰的32位虛擬寄存器中
See https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html


MIR: Mid-level Intermediate Representation:
Methods as control-flow graphs made by sequences of MIR nodes

方法變成了由MIR序列組成的控制流程圖?
(organised in basic blocks).組織形式是BB基本塊,基本塊==方法?


Faithful to DEX bytecode: 1 DEX op → 1 MIR node.

dex操作與MIR一一對應
+ pseudo MIR nodes for annotation purposes.

僞MIR節點爲了註釋的目的???
+ extended MIR nodes for optimisation purposes.

擴展的MIR節點爲了優化的目的

MIR指令不過是把DEX指令給解釋一下 拆分一下 包裝一下,爲了LIR服務


LIR: Low-level Intermediate representation:
Methods as sequences of LIR nodes.
Faithful to instruction set: 1 instruction → 1 LIR node.
+ pseudo LIR nodes for annotation purposes.
Different LIR enums for ARM, ARM64, x86, MIPS.
E.g. NewLIR2(kA64Mov2rr, rw0, rw1) for mov w0, w1.

LIR指令跟機器指令似乎就比較接近了


OAT file:
Cached in /data/dalvik-cache/arm64.
Contain binary executable code.
Contain source DEX bytecode.  

包括了完整DEX代碼,因爲可能還會需要到?有些方法要解釋執行。
Contain metadata for runtime (GC, deoptimization).


From DEX bytecode to MIR nodes:
DEX ops parsed and added as MIR nodes to blocks.
Blocks split at branches/labels: become basic blocks.
Middle-End passes: SSA, type inference, redundant checks elimination.
Pass engine to manage passes.

From MIR to LIR:
Physical regs are “assigned” at this stage.
virtual regs promoted to callee-saved physical regs.

虛擬寄存器變成了物理寄存器,Vx變成了Rx
MIR translated to LIR (big switch statement): caller-saved regs allocated for temps.

LIR optimisation passes:Load hoisting.Load-store elimination.

From LIR to native:
Fixups (branches resolved, instructions replaced if args out-of-range).
LIR translated to binary code.
Global (inter-method) fixups.



The good:
ART is typically 80% faster than Dalvik (Google I/O 2014 - The ART
Runtime).
Quick compiler is quick indeed (on target device must be able to produce
hundreds of MBs in minutes).
The bad:
LIR, MIR are sequences of nodes, rather than graphs:
Difficult to detect dead code and perform code motion.
Difficult to detect instructions sequences (and replace them with better ones).
MIR and LIR are quite different representations: difficult to share
optimisation passes among the two.








suspend-points


What are suspend-points?

1:Checks inserted in generated code to ensure Java threads stop executing
spontaneously when requested to do so.


2:Points of consistency between native-execution, runtime and
interpreted-execution.

好像就是主要用於GC和中斷/debug分析

機器碼實現:





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章