Problem of Context-Insensitive Pointer Analysis
明显Java的方法与上下文,比如调用该函数的变量,有很大关系,比如变量的类型会决定具体调用的是哪个方法实例,之前Context-Insensitive Pointer Analysis比CHA能更好地根据PFG来确定具体调用函数的变量和对应的数据流关系,但是Context-Insensitive Pointer Analysis会把多次调用混杂在一起分析,在实践中带来较大误差。
比如以下例子:
由于调用了两次Number id(Number n),两次的上下文都会被记录到图里,在忽视建图顺序的情况下,int i = x.get()就无法确定x指向的变量,也就无法得知到底应该调用哪个方法实例。
如果我们区分两次调用,分别将其命名为id(n1)和id(n2),那么就能避免将两次调用的关系挤入同一个参数id(n),进一步区分调用的对象从而区分方法实例。
Intro of Context-Sensitive Pointer Analysis
目前最流行的是call-site sensitivity,也就是每个调用的代码行对应一份函数抽象形成的节点,包括method本身的抽象,method-this, method-ret, method-args。
Cloning-Based Context Sensitivity
每个方法,方法中的变量都会用对应的contexts标记上。比如在call-site sensitivity中fun-3:在第3行被调用的fun方法实例,func-3-x:在第3行被调用的fun方法实例中的变量x。
Context-sensitive Heap
Java这种的面向对象语言是非常密集地使用heap的,所以heap上具体的位置也需要使用context sensitivity策略进行区分。不区分的时候方法func-3-x对应的存储位置可能是o8,代表这个变量在第8行被声明并且被放入堆中,但是在区分的情况下,对应的存储位置是3:08,代表context编号为3的情况下,这个变量将在第8行被声明并且被放入堆中。
下面是一个使用了context-sensitive heap技术后能够区分出结果的实例。
Rules
符号定义,注意这里method, variables, objects(实际指向)在空间上都是原空间乘以context空间。相当于是在每个context中都对应拷贝了一份。
Algos
Variants
Call-string sensitivity
相当于记录整个调用栈作为call-site sensitivity
k-Limiting Context Abstraction
限制call-chains的长度为k,一般取k=3
Object Sensitivity
使用receiver object的heap context作为callee context,其他时候按照objects不同来区分context。
Type Sensitivity
就像名字一样的Object Sensitivity