240 likes | 376 Views
Region-Based Model Abstraction. Jeremy Condit Jim Larus Sriram Rajamani Jakob Rehof. OSQ Lunch 7 September 2003. Model Checking for C#. Want to check properties of a C# program e.g., conformance checking for web services The model checking approach:
E N D
Region-BasedModel Abstraction Jeremy Condit Jim Larus Sriram Rajamani Jakob Rehof OSQ Lunch 7 September 2003
Model Checking for C# • Want to check properties of a C# program • e.g., conformance checking for web services • The model checking approach: • Produce a simplified version of program with respect to the property • Check all possible executions of this model
Our Abstraction Technique • We abstract a program by throwing away irrelevant code • Relevant data is identified by a third party • Programmer annotations • Program analysis • Counterexample-driven refinement • Relevant statements and expressions are those that deal with relevant data • Easy, right?
Two Problems • Problem 1: Aliasing • Statements that affect aliasing can be relevant if (…) x = y; x.relevant_field = true; y.relevant_field = false; • Problem 2: Indirection • Relevant data can be buried within other nonsense x.y.z.relevant_field = true;
Example class Transaction { … State s; … } class State { … relevant bool b; … }
Example Transaction x; Transaction y; if (…) { Transaction t1 = new Transaction(); t1.s = new State(); t1.s.b = true; x = t1; } else { Transaction t2 = new Transaction(); t2.s = new State(); t2.s.b = false; x = t2; } if (…) { Transaction t3 = new Transaction(); t3.s = new State(); t3.s.b = true; y = t3; } else { Transaction t4 = new Transaction(); t4.s = new State(); t4.s.b = false; y = t4; } if (x.s.b) … if (y.s.b) … if (x.s.b) …
Solution 1: Program slicing Transaction x; Transaction y; if (…) { Transaction t1 = new Transaction(); t1.s = new State(); t1.s.b = true; x = t1; } else { Transaction t2 = new Transaction(); t2.s = new State(); t2.s.b = false; x = t2; } if (…) { Transaction t3 = new Transaction(); t3.s = new State(); t3.s.b = true; y = t3; } else { Transaction t4 = new Transaction(); t4.s = new State(); t4.s.b = false; y = t4; } if (x.s.b) … if (y.s.b) … if (x.s.b) … Include all statements!
Solution 2: Alias analysis Compute alias sets for x and y: Transaction x; Transaction y; if (…) { Transaction t1 = new Transaction(); t1.s = new State(); t1.s.b = true; x = t1; } else { Transaction t2 = new Transaction(); t2.s = new State(); t2.s.b = false; x = t2; } if (…) { Transaction t3 = new Transaction(); t3.s = new State(); t3.s.b = true; y = t3; } else { Transaction t4 = new Transaction(); t4.s = new State(); t4.s.b = false; y = t4; } if (x.s.b) … if (y.s.b) … if (x.s.b) … x = {t1, t2} y = {t3, t4} if (choose({t1,t2}).s.b) if (choose({t3,t4}).s.b) if (choose({t1,t2}).s.b)
Region-Annotated Example class Transaction[] { … Statehi s; … } class State[] at { … relevant bool b; … }
Region-Annotated Example Transactionhr1ix; Transactionhr2iy; if (…) { Transactionhr1i t1 = new Transactionh1i(); t1.s = new Stateh1i(); t1.s.b = true; x = t1; } else { Transactionhr1i t2 = new Transactionh1i(); t2.s = new Stateh1i(); t2.s.b = false; x = t2; } if (…) { Transactionhr2i t3 = new Transactionh2i(); t3.s = new Stateh2i(); t3.s.b = true; y = t3; } else { Transactionhr2i t4 = new Transaction(); t4.s = new Stateh2i(); t4.s.b = false; y = t4; } if (x.s.b) … if (y.s.b) … if (x.s.b) …
Solution 3: Regions Transactionhr1ix; Transactionhr2iy; if (…) { Transactionhr1i t1 = new Transactionh1i(); t1.s = new Stateh1i(); t1.s.b = true; x = t1; } else { Transactionhr1i t2 = new Transactionh1i(); t2.s = new Stateh1i(); t2.s.b = false; x = t2; } if (…) { Transactionhr2i t3 = new Transactionh2i(); t3.s = new Stateh2i(); t3.s.b = true; y = t3; } else { Transactionhr2i t4 = new Transaction(); t4.s = new Stateh2i(); t4.s.b = false; y = t4; } if (x.s.b) … if (y.s.b) … if (x.s.b) … if (…) { s = new State(); s.b = true; r1[= s; } else { s = new State(); s.b = false; r1[= s; } if (…) { s = new State(); s.b = true; r2[= s; } else { s = new State(); s.b = false; r2[= s; } if (choose(r1).b) … if (choose(r2).b) … if (choose(r1).b) …
Why Regions? • Two phase alias analysis • Static: Identify scope of alias sets • Dynamic: Populate alias sets with objects • Beneficial for model checker • Avoid loss of precision when generating models • Produce more precise alias information by exploiting the power of the model checker • Solves aliasing and indirection problems • Allows fine-grained tuning of trade-off between precision and performance
Our Abstraction • Based on RegJava • Region type system for a Java-like language • Includes proof of soundness • Given a statement or expression p, we define «p¬ to be its abstraction • Distinguish three cases: 1. Relevant data 2. References to relevant data 3. All others
Example: Expressions Example:
Example: Statements Example:
Soundness Theorem • Theorem: For any execution of the original RegJava program, there is a corresponding execution of the model • Proof Sketch: Since we replace occurrences of variables and fields with a choice over the corresponding region, any possible value in the original program will be considered by the model
Context-Sensitivity • Region type systems make our approach context-sensitive void foo[1, 2](Stateh1i s1, Stateh2i s2) { s1.b = true; if (s2.b) … } void foo_model(Set 1, Set2) { choose(1).b = true; if (choose(2).b) … }
Context-Sensitivity, Part 2 • But we still have problems now and then: void foo[](Statehi s1, Statehi s2) { Statehi tmp; if (…) { tmp = s1; } else { tmp = s2; } tmp.b = true; } void foo_model(Set ) { choose().b = true; }
Context-Sensitivity, Part 3 • We can create an even more dynamic model void foo[1, 2](Stateh1i s1, Stateh2i s2) { Statehi tmp; if (…) { tmp = s1; } else { tmp = s2; } tmp.b = true; } void foo_model(Set 1, Set 2) { Set ; if (…) { [= 1; } else { [= 2; } choose().b = true; }
Capturing Correlations • Need to represent important correlations in the model • Solution: Introduce local variables Statehi s = …; s.b = true; s.f = 42; Source: choose().b = true; choose().f = 42; Statehi s = choose(); s.b = true; s.f = 42; Model:
Implementation • Based on Dave Hanson and Todd Proebsting’s research C# compiler • Five stages: • Introduce region variables • Gather constraints and solve • Determine live regions at each AST node • Insert letregion statements to limit region scope • Translate to Zing
The Fine Print • RegJava’s regions use a stack discipline • Letregion statements tend to accumulate near the most general scopes in the program • We’re looking at less restrictive region systems • Region parameters accumulate upward in the class hierarchy • Interfaces can’t be modeled properly • We’re looking at alternative approaches to object-oriented region systems
Related Work • Other model checking projects • SLAM, BLAST, Bandera • Regions in Cyclone • Flow-sensitive Cqual
Conclusion • Region type systems solves several model generation problems: • Aliasing • Indirection • Efficient division of labor: • Model generation phase (static) • Model checking phase (dynamic) • Other compiler analyses may benefit from this approach!