日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ART世界探险(10) - 异常处理

發布時間:2025/3/17 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ART世界探险(10) - 异常处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ART世界探險(10) - 異常處理

對于編譯Java的話,有一個問題不能不考慮,就是異常處理的問題。異常處理是基于Java的語句塊的,翻譯成本地代碼的話,需要針對這些指令的地址進行一下重排。
我們來看下ART是如何實現異常處理的。

Java異常處理

首先復習一下Java。
Java有兩種Exception,一種是普通Exception,另一種是RuntimeException。非RuntimeException,如果沒有處理,就是沒有用try...catch塊包圍或者是throws聲明的話,會編譯不過。
而RuntimeException就沒有這個限制,不處理,就等運行時crash再說吧。

Java源代碼

我們先寫兩個小函數試驗一下:

public void withException(){throw new IllegalStateException();}public void dealWtihException() throws IOException{try{withException();}catch(Exception e){if(e instanceof RuntimeException) throw new IOException();}}

Class字節碼

從字節碼上我們可以看到,dealWithException中,0到4行是記錄在Exception table中的,如果出了Exception,則會跳轉到7開始的語句。
而withException方法,因為拋出的是RuntimeException,也沒有try...catch,所以沒有Exception table.

public void withException();Code:0: new #11 // class java/lang/IllegalStateException3: dup4: invokespecial #12 // Method java/lang/IllegalStateException."<init>":()V7: athrowpublic void dealWtihException() throws java.io.IOException;Code:0: aload_01: invokevirtual #13 // Method withException:()V4: goto 237: astore_18: aload_19: instanceof #15 // class java/lang/RuntimeException12: ifeq 2315: new #16 // class java/io/IOException18: dup19: invokespecial #17 // Method java/io/IOException."<init>":()V22: athrow23: returnException table:from to target type0 4 7 Class java/lang/Exception

Dalvik指令和OAT指令

我們先看只拋個Exception的withException

7: void com.yunos.xulun.testcppjni2.SampleClass.withException() (dex_method_idx=16784)DEX CODE:0x0000: 2200 3908 | new-instance v0, java.lang.IllegalStateException // type@21050x0002: 7010 0642 0000 | invoke-direct {v0}, void java.lang.IllegalStateException.<init>() // method@169020x0005: 2700 | throw v0OatMethodOffsets (offset=0x002778f4)code_offset: 0x00663bdc gc_map: (offset=0x002848e8)OatQuickMethodHeader (offset=0x00663bc0)mapping_table: (offset=0x002deece)vmap_table: (offset=0x0030e0fa)v65535/r30QuickMethodFrameInfoframe_size_in_bytes: 32core_spill_mask: 0x40000000 (r30)fp_spill_mask: 0x00000000 vr_stack_locations:locals: v0[sp + #16]ins: v1[sp + #40]method*: v2[sp + #0]outs: v0[sp + #8]CODE: (code_offset=0x00663bdc size_offset=0x00663bd8 size=116)...0x00663bdc: d1400bf0 sub x16, sp, #0x2000 (8192)0x00663be0: b940021f ldr wzr, [x16]suspend point dex PC: 0x0000GC map objects: v1 ([sp + #40])0x00663be4: f81e0fe0 str x0, [sp, #-32]!0x00663be8: f9000ffe str lr, [sp, #24]0x00663bec: b9002be1 str w1, [sp, #40]0x00663bf0: 79400250 ldrh w16, [tr](state_and_flags)0x00663bf4: 35000290 cbnz w16, #+0x50 (addr 0x663c44)

前面還是保存現場,檢查有沒有被suspend.
然后調用pAllocObject去new一個IllegalStateException對象。
v0是sp+16

0x00663bf8: f94003e1 ldr x1, [sp]0x00663bfc: 52810720 mov w0, #0x8390x00663c00: f940d65e ldr lr, [tr, #424](pAllocObject)0x00663c04: d63f03c0 blr lrsuspend point dex PC: 0x0000GC map objects: v1 ([sp + #40])0x00663c08: b90013e0 str w0, [sp, #16]0x00663c0c: b94013e0 ldr w0, [sp, #16]0x00663c10: b940001f ldr wzr, [x0]suspend point dex PC: 0x0002GC map objects: v0 ([sp + #16]), v1 ([sp + #40])

只要是對象,就要調用構造方法,下面就是計算和調用構造方法。

0x00663c14: b9000fe0 str w0, [sp, #12]0x00663c18: b9400fe1 ldr w1, [sp, #12]0x00663c1c: f94003e0 ldr x0, [sp]0x00663c20: b9400400 ldr w0, [x0, #4]0x00663c24: d2820810 mov x16, #0x10400x00663c28: f2a00050 movk x16, #0x2, lsl #160x00663c2c: f8706800 ldr x0, [x0, x16]0x00663c30: f940181e ldr lr, [x0, #48]0x00663c34: d63f03c0 blr lrsuspend point dex PC: 0x0002GC map objects: v0 ([sp + #16]), v1 ([sp + #40])

從v0(sp+16)把異常對象的引用讀回來,然后調用pDeliverException將其拋出去。

0x00663c38: b94013e0 ldr w0, [sp, #16]0x00663c3c: f942225e ldr lr, [tr, #1088](pDeliverException)0x00663c40: d63f03c0 blr lrsuspend point dex PC: 0x0005GC map objects: v0 ([sp + #16]), v1 ([sp + #40])0x00663c44: f9421e5e ldr lr, [tr, #1080](pTestSuspend)0x00663c48: d63f03c0 blr lrsuspend point dex PC: 0x0000GC map objects: v1 ([sp + #40])0x00663c4c: 17ffffeb b #-0x54 (addr 0x663bf8)

下面再看dealWtihException的:

1: void com.yunos.xulun.testcppjni2.SampleClass.dealWtihException() (dex_method_idx=16778)DEX CODE:0x0000: 6e10 9041 0200 | invoke-virtual {v2}, void com.yunos.xulun.testcppjni2.SampleClass.withException() // method@167840x0003: 0e00 | return-void0x0004: 0d00 | move-exception v00x0005: 2001 4908 | instance-of v1, v0, java.lang.RuntimeException // type@21210x0007: 3801 fcff | if-eqz v1, -40x0009: 2201 2008 | new-instance v1, java.io.IOException // type@20800x000b: 7010 ca41 0100 | invoke-direct {v1}, void java.io.IOException.<init>() // method@168420x000e: 2701 | throw v1OatMethodOffsets (offset=0x002778dc)code_offset: 0x0066341c gc_map: (offset=0x002ce33a)OatQuickMethodHeader (offset=0x00663400)mapping_table: (offset=0x00308696)vmap_table: (offset=0x0030e0fa)v65535/r30QuickMethodFrameInfoframe_size_in_bytes: 48core_spill_mask: 0x40000000 (r30)fp_spill_mask: 0x00000000 vr_stack_locations:locals: v0[sp + #28] v1[sp + #32]ins: v2[sp + #56]method*: v3[sp + #0]outs: v0[sp + #8]CODE: (code_offset=0x0066341c size_offset=0x00663418 size=288)...0x0066341c: d1400bf0 sub x16, sp, #0x2000 (8192)0x00663420: b940021f ldr wzr, [x16]suspend point dex PC: 0x0000GC map objects: v2 ([sp + #56])0x00663424: f81d0fe0 str x0, [sp, #-48]!0x00663428: f90017fe str lr, [sp, #40]0x0066342c: b9003be1 str w1, [sp, #56]0x00663430: 79400250 ldrh w16, [tr](state_and_flags)0x00663434: 350006b0 cbnz w16, #+0xd4 (addr 0x663508)

本地變量:
v0是sp+28
v1是sp+32

開始先將sp+56(v2)清0.
然后調用我們自己寫的withException方法。

0x00663438: b9403be0 ldr w0, [sp, #56]0x0066343c: b940001f ldr wzr, [x0]suspend point dex PC: 0x0000GC map objects: v2 ([sp + #56])0x00663440: b9001be0 str w0, [sp, #24]0x00663444: b9401be1 ldr w1, [sp, #24]0x00663448: b9400020 ldr w0, [x1]0x0066344c: f9418c00 ldr x0, [x0, #792]0x00663450: f940181e ldr lr, [x0, #48]0x00663454: d63f03c0 blr lrsuspend point dex PC: 0x0000GC map objects: v2 ([sp + #56])

返回值也用不到,所以直接返回了。

0x00663458: f94017fe ldr lr, [sp, #40]0x0066345c: 9100c3ff add sp, sp, #0x30 (48)0x00663460: d65f03c0 retcatch entry dex PC: 0x0004

下面是處理Exception的部分:

Exception的類型放到w0中,然后去判斷類型是否已經初始化過了。

0x00663464: b9408a40 ldr w0, [tr, #136](exception)0x00663468: b9008a5f str wzr, [tr, #136](exception)0x0066346c: b9001fe0 str w0, [sp, #28]0x00663470: f94003e0 ldr x0, [sp]0x00663474: b9400800 ldr w0, [x0, #8]0x00663478: b9613000 ldr w0, [x0, #8496]0x0066347c: 340004c0 cbz w0, #+0x98 (addr 0x663514)

如果沒有初始化,那就真接跳0x663490,返回

0x00663480: b9001be0 str w0, [sp, #24]0x00663484: b9401fe0 ldr w0, [sp, #28]0x00663488: b9401be1 ldr w1, [sp, #24]0x0066348c: 52800002 mov w2, #0x00x00663490: 340000a0 cbz w0, #+0x14 (addr 0x6634a4)

對象已經初始化過了,就去調pInstanceofNonTrivial去做instanceof檢查。

0x00663494: b9400002 ldr w2, [x0]0x00663498: 6b01005f cmp w2, w10x0066349c: 54000441 b.ne #+0x88 (addr 0x663524)0x006634a0: 52800022 mov w2, #0x1

下面這段是判斷不是RuntimeException的子類,所以跳回,結束的情況。0x00663458是上面的返回部分的代碼。

0x006634a4: b90023e2 str w2, [sp, #32]0x006634a8: b94023e0 ldr w0, [sp, #32]0x006634ac: 7100001f cmp w0, #0x0 (0)0x006634b0: 1a9f17e1 cset w1, eq0x006634b4: 2a0103e0 mov w0, w10x006634b8: 35fffd00 cbnz w0, #-0x60 (addr 0x663458)

這里調用pAllocObject去new IOException的對象。

0x006634bc: f94003e1 ldr x1, [sp]0x006634c0: 52810400 mov w0, #0x8200x006634c4: f940d65e ldr lr, [tr, #424](pAllocObject)0x006634c8: d63f03c0 blr lrsuspend point dex PC: 0x0009GC map objects: v0 ([sp + #28]), v2 ([sp + #56])0x006634cc: b90023e0 str w0, [sp, #32]0x006634d0: b94023e0 ldr w0, [sp, #32]0x006634d4: b940001f ldr wzr, [x0]suspend point dex PC: 0x000bGC map objects: v0 ([sp + #28]), v1 ([sp + #32]), v2 ([sp + #56])

下面當然是調IOException的構造方法了:

0x006634d8: b9001be0 str w0, [sp, #24]0x006634dc: b9401be1 ldr w1, [sp, #24]0x006634e0: f94003e0 ldr x0, [sp]0x006634e4: b9400400 ldr w0, [x0, #4]0x006634e8: d281cc10 mov x16, #0xe600x006634ec: f2a00050 movk x16, #0x2, lsl #160x006634f0: f8706800 ldr x0, [x0, x16]0x006634f4: f940181e ldr lr, [x0, #48]0x006634f8: d63f03c0 blr lrsuspend point dex PC: 0x000bGC map objects: v0 ([sp + #28]), v1 ([sp + #32]), v2 ([sp + #56])

最后調用pDeliveryException拋出去。

0x006634fc: b94023e0 ldr w0, [sp, #32]0x00663500: f942225e ldr lr, [tr, #1088](pDeliverException)0x00663504: d63f03c0 blr lrsuspend point dex PC: 0x000eGC map objects: v0 ([sp + #28]), v1 ([sp + #32]), v2 ([sp + #56])0x00663508: f9421e5e ldr lr, [tr, #1080](pTestSuspend)0x0066350c: d63f03c0 blr lrsuspend point dex PC: 0x0000GC map objects: v2 ([sp + #56])0x00663510: 17ffffca b #-0xd8 (addr 0x663438)

pInitializeType是檢查類型是否已經初始化過了。

0x00663514: 52810920 mov w0, #0x8490x00663518: f9410a5e ldr lr, [tr, #528](pInitializeType)0x0066351c: d63f03c0 blr lrsuspend point dex PC: 0x0005GC map objects: v0 ([sp + #28]), v2 ([sp + #56])0x00663520: 17ffffd8 b #-0xa0 (addr 0x663480)

最后是instanceof的實現,pInstanceofNonTrivial

0x00663524: aa0103e0 mov x0, x10x00663528: aa0203e1 mov x1, x20x0066352c: f940fa5e ldr lr, [tr, #496](pInstanceofNonTrivial)0x00663530: d63f03c0 blr lrsuspend point dex PC: 0x0005GC map objects: v0 ([sp + #28]), v2 ([sp + #56])0x00663534: 2a0003e2 mov w2, w00x00663538: 17ffffdb b #-0x94 (addr 0x6634a4)

異常處理相關指令總結

Java字節碼Dalvik指令OAT過程
athrowthrow v0pDeliverException

總結

以上是生活随笔為你收集整理的ART世界探险(10) - 异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人黄色在线观看 | 日韩欧美精品久久 | 北岛玲av在线 | 韩国无码一区二区三区精品 | 国产尤物在线观看 | 少妇人妻无码专区视频 | 操操影视 | 看一级大片 | 亚洲经典一区 | 国产精品三级在线观看 | 香蕉视频在线观看免费 | 亚洲精品wwww | 久久久久久久色 | 好吊视频一二三区 | 国产成人精品电影 | 色偷偷成人 | 久久久精品免费看 | a级性生活视频 | 各处沟厕大尺度偷拍女厕嘘嘘 | 中文字幕+乱码+中文乱码www | 欧美一区二区三区 | 国产一区麻豆 | 久草最新| 亚洲性猛交富婆 | 亚洲粉嫩 | 用力插视频 | 欧美理论在线 | 男插女青青影院 | 丰满岳跪趴高撅肥臀尤物在线观看 | 在线观看国产小视频 | 人妻无码一区二区三区久久99 | 欧美另类高清videos的特点 | 国产免费一区二区三区最新不卡 | www.亚洲天堂.com | 亚洲影视中文字幕 | 老司机激情视频 | youjizz.com中国| 性xx紧缚网站 | 天降女子在线 | 91麻豆精品一区二区三区 | 久久高清一区 | 日本老师巨大bbw丰满 | 欧美一级一片 | 日韩av片在线看 | 久久久久久无码精品人妻一区二区 | 无码任你躁久久久久久老妇 | 成人第一页 | 黄网视频在线观看 | 亚洲最新在线观看 | 在线中文字幕观看 | 欧美性一区二区 | 欧美一区二区成人 | 亚洲男人第一天堂 | 精品国产毛片 | 亚洲精品一区二区三区新线路 | 国产小视频在线看 | 中文在线视频 | 国产精品国产三级国产播12软件 | 日韩少妇精品 | 不许穿内裤随时挨c调教h苏绵 | 一级片aaa | 免费观看h片 | 日本综合在线 | 日本偷偷操 | 色窝窝无码一区二区三区 | www.com污| 日韩中文一区二区 | 欧美做爰猛烈床戏大尺度 | 97神马影院 | 911美女片黄在线观看游戏 | 在线免费观看av网址 | 色网视频 | 蜜桃精品久久久久久久免费影院 | 亚洲视频在线免费 | av综合网站 | 高清av一区 | 色撸撸av | 亚洲色图50p| 亚洲欧美成人一区二区 | 精品伦理一区二区 | 王者后宫yin肉h文催眠 | 欧美精品午夜 | 天天插综合 | 成人在线免费小视频 | 国产一区二区综合 | 日本一区二区三区电影在线观看 | 久久久九九九热 | 精品国产精品国产偷麻豆 | 伊人888 | 国产良妇出轨视频在线观看 | 麻豆91茄子在线观看 | 五月婷六月 | 波多野结衣不卡视频 | 视频二区三区 | 麻豆传谋在线观看免费mv | 操色网| 久久xxxx| 国产91色 | 好吊妞在线观看 |