eda045f program analysis
play

EDA045F: Program Analysis LECTURE 5 BONUS: BASIC CALLGRAPHS - PowerPoint PPT Presentation

EDA045F: Program Analysis LECTURE 5 BONUS: BASIC CALLGRAPHS Christoph Reichenbach The Call Graph void f(char *s) { for (char *p = s; *p; p++) { *p = up(*p); } puts(s); } int main(int argc, char *argv) { char up(char c) { if (argc > 1)


  1. EDA045F: Program Analysis LECTURE 5 BONUS: BASIC CALLGRAPHS Christoph Reichenbach

  2. The Call Graph void f(char *s) { for (char *p = s; *p; p++) { *p = up(*p); } puts(s); } int main(int argc, char *argv) { char up(char c) { if (argc > 1) { if (c >= ’a’ && c <= ’z’) { f(argv[0]); return c - (’a’ - ’A’); } } g(); return c; return 0; } } void g(void) { puts("Hello, World!"); } 2 / 15

  3. The Call Graph void f(char *s) { for (char *p = s; *p; p++) { *p = up(*p); } puts(s); } int main(int argc, char *argv) { char up(char c) { if (argc > 1) { if (c >= ’a’ && c <= ’z’) { f(argv[0]); return c - (’a’ - ’A’); } } g(); return c; return 0; } } void g(void) { puts("Hello, World!"); } 2 / 15

  4. The Call Graph ◮ G call = � P , E call � ◮ Connects procedures from P via call edges from E call ◮ ‘Which procedure can call which other procedure?’ ◮ Often refined to: ‘Which call site can call which procedure?’ ◮ Used by program analysis to find procedure call targets up f main g 3 / 15

  5. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 4 / 15

  6. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 4 / 15

  7. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 4 / 15

  8. Dynamic Dispatch: Call Graph Challenge: Computing the precise call graph: A.<init>() A.f() Main.main() A.g() B.<init>() a.f B.g() a.g C.<init>() a2.g C.g() direct call D.<init>() virtual call D.g() 5 / 15

  9. Summary ◮ Call Graphs capture which procedure calls which other procedure ◮ For program analysis, further specialised to map: Callsite → Procedure ◮ Direct calls: straightforward ◮ Virtual calls (dynamic dispatch): ◮ Multiple targets possible for call ◮ Not straightforward 6 / 15

  10. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 7 / 15

  11. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for ( A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 7 / 15

  12. Class Hierarchy Analysis Object Main A main(String[]) f() g() B C D g() g() g() ◮ Use declared type to determine possible targets 8 / 15

  13. Class Hierarchy Analysis Object Main A main(String[]) f() g() B C D g() g() g() ◮ Use declared type to determine possible targets ◮ Must consider all possible subtypes ◮ In our example: assume a.f can call any of: A.f() , B.f() , C.f() , D.f() 8 / 15

  14. Class Hierarchy Analysis: Example A.<init>() A.f() Main.main() A.g() B.<init>() a.f B.g() a.g C.<init>() a2.g C.g() direct call D.<init>() virtual call D.g() CHA prediction 9 / 15

  15. Class Hierarchy Analysis: Example A.<init>() A.f() Main.main() A.g() B.<init>() a.f B.g() a.g C.<init>() a2.g C.g() direct call D.<init>() virtual call D.g() CHA prediction 9 / 15

  16. Summary ◮ Call Hierarchy Analysis resolves virtual calls a . f () by: ◮ Examining static types T of receivers ( a : T ) ◮ Finding all subtypes S < : T ◮ Creating call edges to all S . f , if S . f exists ◮ Sound ◮ Assuming strongly and statically typed language with subtyping ◮ Not very precise 10 / 15

  17. Rapid Type Analysis ◮ Intuition: ◮ Only consider reachable code ◮ Ignore unused classes ◮ Ignore classes instantiated only by unused code 11 / 15

  18. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for ( A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  19. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  20. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  21. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  22. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  23. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  24. Finding Calls and Targets class Main { public void main(String[] args) { class A { A[] as = { new A(), new B() }; public A for (A a : as) { f() { return new C(); } A a2 = a.f(); print(a.g()); public String print(a2.g()); g() { return "A"; } } } } } class D extends A { class C extends A { class B extends A { @Override @Override @Override public String public String public String g() { return "D"; } g() { return "A"; } g() { return "B"; } } } } 12 / 15

  25. Rapid Type Analysis: Example A.<init>() A.f() Main.main() A.g() B.<init>() a.f B.g() a.g C.<init>() a2.g C.g() direct call D.<init>() virtual call D.g() RTA prediction 13 / 15

  26. Rapid Type Analysis: Example A.<init>() A.f() Main.main() A.g() B.<init>() a.f B.g() a.g C.<init>() a2.g C.g() direct call D.<init>() virtual call D.g() RTA prediction 13 / 15

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend