編譯一個.java在Android上運行並經過oatdump反彙編查看oat文件
咱們有一個Java程序helloworld:java
public class HelloWorld { int add_call(int a,int b){ return a + b; } public static void main(String[] args) { HelloWorld m = new HelloWorld(); int c = m.add_call(1, 2); System.out.println("Hello xianlong"); } }
經過javac將程序編譯成class文件,helloworld.class
javac Helloworld.java
接下來將.class經過dx工具轉換成dex文件
./dx --dex --output=HelloWorld.dex HelloWorld.class
工具
這裏要注意的是,個人dx文件使用的是以前系統源碼中的prebuilts/sdk/tool
中的dx
。JDK
使用的是1.6。(1.8版本會出現錯誤)ui
以後將咱們的HelloWorld.dex
經過adb push到手機中,接下來經過dalvikvm就能夠運行該dex文件。 dalvikvm -cp HelloWorld.dex HelloWorld
(這裏的-cp是指class path)spa
若是咱們想dump一下oat文件,就要藉助oatdump。 執行: oatdump --oat-file=HelloWorld.odex > dump.txt
就能夠把dump結果保存到dump.txt中。 接下來咱們打開該文件能夠看到:(部分)code
0: LHelloWorld; (offset=0x0000064c) (type_idx=1) (StatusInitialized) (OatClassSomeCompiled) 0: void HelloWorld.<init>() (dex_method_idx=0) DEX CODE: 0x0000: 7010 0400 0000 | invoke-direct {v0}, void java.lang.Object.<init>() // method@4 0x0003: 7300 | return-void-no-barrier OatMethodOffsets (offset=0x00000000) code_offset: 0x00000000 OatQuickMethodHeader (offset=0x00000000) vmap_table: (offset=0x00000000) QuickMethodFrameInfo frame_size_in_bytes: 0 core_spill_mask: 0x00000000 fp_spill_mask: 0x00000000 vr_stack_locations: ins: v0[sp + #8] method*: v1[sp + #0] outs: v0[sp + #8] CODE: (code_offset=0x00000000 size_offset=0x00000000 size=0) NO CODE! 1: void HelloWorld.main(java.lang.String[]) (dex_method_idx=2) DEX CODE: 0x0000: 2200 0100 | new-instance v0, HelloWorld // type@TypeIndex[1] 0x0002: 7010 0000 0000 | invoke-direct {v0}, void HelloWorld.<init>() // method@0 0x0005: 1211 | const/4 v1, #+1 0x0006: 1222 | const/4 v2, #+2 0x0007: e930 0b00 1002 | invoke-virtual-quick {v0, v1, v2}, // vtable@11 0x000a: 6200 0000 | sget-object v0, Ljava/io/PrintStream; java.lang.System.out // field@0 0x000c: 1a01 0100 | const-string v1, "Hello xianlong" // string@1 0x000e: e920 2c00 1000 | invoke-virtual-quick {v0, v1}, // vtable@44 0x0011: 7300 | return-void-no-barrier OatMethodOffsets (offset=0x00000658) code_offset: 0x00000000 OatQuickMethodHeader (offset=0x00001008) vmap_table: (offset=0x000003a4) quickened data QuickMethodFrameInfo frame_size_in_bytes: 0 core_spill_mask: 0x00000000 fp_spill_mask: 0x00000000 vr_stack_locations: locals: v0[sp + #4294967280] v1[sp + #4294967284] v2[sp + #4294967288] ins: v3[sp + #8] method*: v4[sp + #0] outs: v0[sp + #8] v1[sp + #12] v2[sp + #16] CODE: (code_offset=0x00000000 size_offset=0x0000101c size=0) NO CODE! 2: int HelloWorld.add_call(int, int) (dex_method_idx=1) DEX CODE: 0x0000: 9000 0203 | add-int v0, v2, v3 0x0002: 0f00 | return v0
發現都是dex code沒有code,看來咱們須要手動編譯才能AOT的生成機器碼。(以後搞明白了會將手動AOT的方法添加在這個後邊。)get