Problem of Context-Insensitive Pointer Analysis
在 CI(Content Insensitive)中,处理 x.get() 时,因为 x 是Number类型,所以这里会 Dispatch 到两个方法,并且将两条边都加入 CG 中。但是,其实可以看到有一条边是明显冗余的,在实际执行中并不是 x 的指向目标,这在常量传播分析当中会直接导致 i 成为一个 NAC 。
采用 CS(Content Sensitive)后,由于对上下文敏感了,所以现在对于 id(n) 的调用,分为两次去分析。
Introduction
再简单总结一下 CI 带来的imprecision 的原因。
在动态执行中,一个方法可能在不同的调用上下文中被多次调用,而在不同调用上下文中,该方法中的变量可能指向不同的对象,在 CI 指针分析中,不同上下文的对象被混合并传播到程序的其它部分(通过返回值或副作用),导致虚假的数据流。
上下文敏感性模型通过区分不同上下文的不同数据流来调用上下文,以提高精度。最古老且最著名的上下文敏感性策略是调用点敏感性( call-string ):每个方法上下文都表示为调用点的链,即方法的一个调用点、;调用者的一个调用点;调用者的调用者的一个调用点等。
在 CS 中,这里的方法 id(Number)有两个上下文:[1] 和 [2]。
Cloning-Based Context Sensitivity
基于克隆的上下文敏感分析是最直接的方法来实现上下文敏感性。在基于克隆的上下文相关指针分析中,每种方法都由一个或多个上下文来限定,变量也由上下文(从它们声明的函数继承而来)进行限定,本质上,每种方法和其变量都被克隆,每个上下文一个克隆。
Context-Sensitive Heap
OO 程序(例如 Java )通常是堆密集型,在实践中,为了提高精度,对堆抽象也应用上下文敏感性,抽象对象也由上下文(称为堆上下文)限定,最常见的做法是从分配对象的方法中继承上下文。上下文敏感的堆抽象在分配站点抽象之上提供了一个更细粒度的堆模型。
根据不同的上下文,确定堆抽象的指针指向。
Why Context-Sensitive Heap Improve Precision?
在动态执行中,一个分配点可以在不同的调用上下文中创建多个对象,不同对象(由同一站点分配)可能使用不同的数据流进行操作,例如,将不同的值存储到它们的字段中,在指针分析中,没有堆上下文的情况下分析此类代码可能会通过将不同上下文的数据流合并到一个抽象对象中而失去精度,相比之下,通过堆上下文区分来自同一分配点的不同对象可以获得更高的精度。
这里用一个例子来体会对堆抽象进行上下文敏感分析带来的精度提升:
在没有 C.S. Heap 的情况下,会将冗余的信息流向 x 的字段。
Context Sensitive Pointer Analysis: Rules
Domain and Notations
在上下文相关分析中,程序元素由上下文限定:
其实就是在原来的基础上加上了限定的上下文。
Rules
Kind | Statement | Rule(under context c) | PFG Edge |
New | i: x = new T() | N/A | |
Assign | x = y | c:x ← c:y | |
Store | x.f = y | c′:oi.f ← c:y | |
Load | y = x.f | c:y ← c′:oi.f | |
Call | l: r = x.k(a1,…,an) | ||
也就是在原来 CI 的基础上加了上下文信息,这里具体的 Select 方法确定上下文信息在后面会介绍。