目錄:
- Motivation
- 調用圖構建
- 過程間控制流分析
- 過程間數據流分析
重點:
學習如何利用類層級分析來構建調用圖;過程間控制流/數據流分析;過程間的常量傳播。
1.Motivation
問題:過程內的分析未考慮函數調用,導致分析不精確。
過程間分析:Inter-procedural Analysis,考慮函數調用,又稱為全程序分析(Whole Program Analysis),需要構建調用圖,加入Call edges和Return edges。
2.調用圖構建
(1)調用圖
定義:本質是調用邊的集合,從調用點(call-sites)到目標函數(target methods / callees)的邊。
示例:
應用:是所有過程間分析(跨函數分析)的基礎,程序優化,程序理解,程序調試。
(2)面向對象語言的調用圖構造(Java)
代表性算法:從上往下精度變高,速度變慢,重點分析第1、4個算法。
- Class hierarchy analysis(CHA)
- Rapid type analysis(RTA)
- Variable type analysis(VTA)
- Pointer analysis(k-CFA)
Java調用分類:
Static call | Special call | Virtual call | |
---|---|---|---|
指令 | invokestatic | invokespecial | invokeinterface、 invokevirtual |
Receiver objects(返回后賦值的目標對象) | × | ? | ? |
目標函數 | Static函數 | 構造函數、 私有函數、父類的實例函數 | 其他實例函數 |
目標函數個數 | 1 | 1 | ≥1 (polymorphism多態性) |
何時確定 | 編譯時 | 編譯時 | 運行時 |
Method Dispatch:最難的是Virtual call,其中關鍵步驟是Method Dispatch,就是找到最終調用的實際函數。
virtual call在程序運行時才能得到,基于2個要素得到:
reciever object的具體類型:c
-
調用點的函數簽名:m。(通過signature可以唯一確定一個函數)
- signature = 函數所在的類 + 函數名 + 描述符
- 描述符 = 返回類型 + 參數類型
簡記為C.foo(P, Q, R)
5-2-2-virtual_call.png
(3)Method Dispatch(virtual call)
定義:用Dispatch(c, m)來模擬動態Method Dispatch過程,c表示reciever object,m表示函數簽名。
解釋:若該類的非抽象方法(實際可執行的函數主體)中包含和m相同名字、傳遞/返回參數的m‘,則直接返回;否則到c的父類中找。
示例:
(4)Class Hirarchy Analysis (CHA) 類層級分析
目的:根據每個virtual call 的 receiver varible 的聲明類型來求解所有可能調用的目標函數。如 A a = ... ;
a.foo();
這個a就是receiver varible,聲明類型就是A。假定a可以指向A以及A所有子類對象,CHA的過程就是從A和子類中去找目標函數。
算法:Resolve(cs)——利用CHA算法找到調用點所有可能的調用目標。
算法示例:
算法應用:
錯誤:以上b.foo()的調用目標 C.foo()和D.foo()是錯誤的,因為已經指定了是B類型,所以b.foo()根本不會調用C、D的foo()。因為CHA只考慮聲明類型,也就是B,導致準確度下降。多態性就是說,父類可以引用子類的對象,如B b=new C()
。
優缺點:CHA優點是速度快,只考慮聲明類型,忽略數據流和控制流;缺點是準確度低。
總結:本類中有同名函數就在本類和子類找,沒有就從父類找,接著找父類的子類中的同名函數(CHA分析)。
(5)利用CHA構造調用圖
算法:遍歷每個函數中的每個調用指令,調用CHA的Resolve()找到對應的目標函數和調用邊,函數+調用邊=調用圖。
示例:
3.過程間控制流分析
定義:過程間控制流圖ICFG = CFG + (Call edges + Return edges)。
- Call edges:連接調用點和目標函數入口
- Return edges:從return語句連到Return site(Call site后面一條語句)
示例:
4.過程間數據流分析
說明:對ICFG進行數據流分析,沒有標準的一套算法。
對比:
Intraprocedural | Interprocecdural | |
---|---|---|
程序表示 | CFG | ICFG = CFGs + call & return edges |
轉換規則 | Node transfer | Node transfer + edge transfer |
常量傳播數據流分析:
- Node transfer:與過程內分析相同,對每個調用點,將等號左邊部分去掉。
- Call edge transfer:傳參
- Return edge transfer:傳返回值
常量傳播示例:
說明:黃色背景邊必須有,從b = addOne(a)
到c=b-3
,a通過此邊傳遞,b通過addOne()傳遞。若a也通過addOne()傳遞,會額外消耗系統資源。