Modular Heap Analysis Of Higher Order ProgramsRavichandhran Madhavan + *Ganesan Ramalingam *Kapil Vaswani *
* Microsoft Research India+ EPFL, Switzerland
Goal 1: Analyze Modularly
• Compute succinct summaries for procedures
• Summaries: total functions approximating the relational semantics
𝛾 (𝑆𝑢𝑚𝑚𝑎𝑟 𝑦 𝑃)
Input State
Output States
[𝑃 ]𝑐⊇
Goal 2: Track Heap Information
• The summary of a procedure should capture the transformation of the input mutable heap
Goal 3: Analyze HO programs
• Should be able to summarize higher order procedures• Input state includes data as well as code
Challenge• Indirect procedure calls esp. Call backs• Virtual method calls, function pointer calls, lambda expressions
Foo(PTR* p , FP* fp){ *p = (**fp)(0);}
Count() { iter = this.iterator(); i = 0; while(iter.HasNext()) { iter.next(); i++; } }
Challenge• All widely used languages support Higher Order constructs
But how do existing modular analyses
handle them ?
A Common Hack• Estimate the targets of the indirect calls through an
inexpensive analysis E.g.
• CHA, RTI analysis for OO programs• Light weight pointer analysis …
• Construct a conservative call graph
• Analyze bottom up
Limitations of the Hack• Over-approximated targets
• A call-graph is necessarily context insensitive for HO programs
A
C
B
D
EB’s context
A’s context
Limitations of the Hack• Inability to construct client independent summaries
Foo(FP* fp){ (*fp)(…);}
m1(){ …}
C1(){ Foo(m1);}
m2(){ …}
C2(){ Foo(m2)}
Resolved to m1
Summary:
Limitations of the Hack
• Reuse of summaries possible only within an analysis• Need to analyze libraries together with clients• Need to reanalyze libraries for each new client
Doesn’t allow library compositional analysis
Our approach
• Use existing techniques for summarizing first-order code segments:
• [Whaley, Salcianu, Rinard, OOPSLA ‘99, VMCAI ’04]• [Madhavan et al., SAS ‘11]
• Retain the call backs in the summaries
Our approach
• Perform as much simplification as possible without the knowledge of the calling context
• Eliminate fully resolved calls from the summaries
Enables efficient library compositional analysis
Illustration1
7
2
4
3
5
6
*fp(a,b)𝑆24
𝑆13𝑆12
𝑆56
𝑆67𝑆47
Illustration1
7
2
4
3
5
6
*fp(a,b)𝑆24
𝑆13𝑆12
𝑆56
𝑆67𝑆47
Illustration
3
5
6
*fp(a,b)
𝑆13
𝑆56
𝑆67
7
1
𝜏17
Illustration
3
5
*fp(a,b)
7
1
𝜏17
𝜏57
𝜏13
Exploiting Local Context
3
5
*fp(a,b)
7
1
𝜏17
𝜏57=(𝜏 𝑙 ,𝜏′)
𝜏13
3
5
*fp(a,b)
7
1
𝜏17
𝜏 ′
𝜏13
𝜏 𝑙∘𝜏13
Frame Rule
Exploiting Local Context
3
5
*fp(a,b)
7
1
𝜏17
𝜏57=(𝜏 𝑙 ,𝜏′)
𝜏13
3
5
*fp(a,b)
7
1
𝜏 ′
𝜏13Frame Rule
Flow Insensitive Abstraction
3
5
*fp(a,b)
7
1
𝜏
𝜏
𝜏
𝜏
3
5
*fp(a,b)
7
1
𝜏57
𝜏13
𝜏17
𝜏=𝜏13⊔𝜏17⊔𝜏57
Flow Insensitive Abstraction
(𝜏 , \{𝑐1 ,… ,𝑐𝑘 \})
HO summary = First order summary +
set of call backs
𝑐1…𝑐𝑘
2
3
4
1
𝜏
𝜏
𝜏
𝜏
Composition Operation
(𝜏1 ,𝜔1)𝑆1;𝑆2 ;…;𝑆𝑛 𝑐1…𝑐𝑘
2
3
4
1
𝜏1
𝜏1
𝜏1
𝜏1
(𝜏2 ,𝜔2)𝑆𝑛+1;…;𝑆𝑚 𝑑1…𝑑 𝑗
6
7
8
5
𝜏2
𝜏2
𝜏2
𝜏2
ID
Composition Operation
(𝜏1 ,𝜔1)𝑆1;𝑆2 ;…;𝑆𝑛
(𝜏2 ,𝜔2)𝑆𝑛+1;…;𝑆𝑚
𝑐1…𝑐𝑘
2
3
4
1
𝜏1
𝜏1
𝜏1
𝜏1
𝑑1…𝑑 𝑗
6
7
8
5
𝜏2
𝜏2
𝜏2
𝜏2
ID𝜏2∘𝜏1
Composition Operation
• where , is the composed abstract state
• When the first order summaries (and hence composition) are isotonic:
(𝜏2 ,𝜔2 )∘ (𝜏1 ,𝜔1 )=(𝜏2∘𝜏1 ,𝜔1∪𝜔2)
Handling Direct Calls• Handle direct calls via summary composition
(𝜏𝑒 ,𝜔𝑒)
(𝜏𝑟 ,𝜔𝑟)
¿
Call backs in the callee are inlined in the caller
Indirect call Resolution
(𝜏 , \{𝑐1 \})
3
5
7
1
𝜏 𝜏
𝜏
𝑐1B (𝜏𝑏 , \{𝑐2 \})
(𝜏 ∘𝜏𝑏 )∗∘𝜏
(𝜏2 , \{𝑐1 ,𝑐2 \})
𝜏
A
Indirect Call Resolution
A
(𝜏 , \{𝑐1 \})
calls B
B
(𝜏4❑ , \{𝑐1 ,𝑐2 ,𝑐3 \})(𝜏2
❑ , \{𝑐1 ,𝑐2 \})
calls C
C
(𝜏3❑ , \{𝑐1 ,𝑐2 ,𝑐3 \})
calls B calls A
(𝜏𝑏 , \{𝑐2 \})
(𝜏𝑐 , \{𝑐3 \})
Indirect Call Resolution
A
(𝜏 𝑖− 1❑ ,𝜔 𝑖−1)
…
BC
(𝜏𝑏 , \{𝑐2 \})
(𝜏𝑐 , \{𝑐3 \})
(𝜏 𝑖❑ ,𝜔𝑖)…..
Fixed point
Eliminating resolved calls
(a) is Non escaping.Unreachable from
indirect calls and prestate
𝑝2
(b) and are unreachable from prestate and other call backs
𝑓𝑝1
*fp1
…
Resolved calls
Foo
*fp2
𝑓𝑝2 …
𝑝1Bar
Experimental Evaluation
• Applied to Purity/Side-effects Analysis for C# libraries
• Every method is classified as:
• Pure – No side-effects • Conditionally Pure – Purity depends on the calling context• Impure – Has side-effects• Impure and Incomplete – Has side-effects and can have more
depending on the calling context
Experimental ResultsBenchmark LOC Pure C-Pure Impure I-Impure Time
DocX 10K ~ 1 min
FB APIs 2.2% 32%
Data Disp. 57%
Test APIs
Json Libs
Quickgraph
Refactory libs 30% 8%
Utility Libs 32% 8%
PDF libs 28.4%
GPS libs 250K ~ 2 hrs
10 – 20%
15 – 30%
20 – 30%
2 – 27 min
Analysis StatisticsBenchmark Unresolved
CallsNon Escaping Abs. Objects
DocX
FB APIs 9%
Data Disp.
Test APIs
Json Libs 7.3
Quickgraph
Refactory libs
Utility Libs
PDF libs 37%
GPS libs 5.9
2 – 4
10 – 33 %
Comparison with CHA CG based Bottom up Analysis
Benchmark Time # of SCCs Avg. Scc size
DocX 12x 0 NA
FB APIs 11x 3x 1.5x
Data Disp. 6x 6x
Test APIs 6x 2x 1.25x
Json Libs 2x 6x
Quickgraph 11x 33x
Refactory libs 1.4x 5.6x
Utility Libs 30x 4x 12x
PDF libs 2x 3.5x 1.5x
Conclusion
• A principled approach
• Formalized as an Abstract Interpretation
• A generic theory agnostic to the underlying compositional heap analysis
• Goto www.rise4fun.com/seal for a hands-on experience