1 / 27

Exception

Exception. Compiler Baojian Hua bjhua@ustc.edu.cn. Exception. Exception is for error-handling Invalid input Invalid resource state file not exists, network error, … error execution condition divide-by-zero, … In real production code, error-handling code may be a large part

ernie
Télécharger la présentation

Exception

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exception Compiler Baojian Hua bjhua@ustc.edu.cn

  2. Exception • Exception is for error-handling • Invalid input • Invalid resource state • file not exists, network error, … • error execution condition • divide-by-zero, … • In real production code, error-handling code may be a large part • 30%-50% or more

  3. Scale the language e -> num -> id -> e1 bop e2 -> throw -> try e1 catch e2 // Example: try 3 catch 5 try (3 + throw) catch 5

  4. Semantics throw: // abort the current execution, and notify the // system some bad things happen! // Q: what kind of bad things? try e1 catch e2: // first execute e1, if e1 runs smoothly, then // its value is return; else run e2 and return // its value. // Q: what about e2 “throw”?

  5. Two strategies • Setjmp/longjmp-based • global “goto” • C’s primitive exception • Table-driven method • more complex and more space usage • but faster

  6. Setjmp/longjmp buffer buf; void f () { if (0==setjmp (buf)) g (); } void g () { h (); } void h () { longjmp (buf, 1); }

  7. Setjmp/longjmp struct context { int ebx; int edi; int esi; int ebp; int esp; int eip; }; typedef struct context buffer[1];

  8. Setjmp/longjmp buf buffer buf; void f () { if (0==setjmp (buf)) g (); } void g () { h (); } void h () { longjmp (buf, 1); } frame f

  9. Setjmp/longjmp buf buffer buf; void f () { if (0==setjmp (buf)) g (); } void g () { h (); } void h () { longjmp (buf, 1); } frame f

  10. Setjmp/longjmp buf buffer buf; void f () { if (0==setjmp (buf)) g (); } void g () { h (); } void h () { longjmp (buf, 1); } frame f frame g frame h

  11. Compiling to setjmp/longjmp • Basic idea: • try e1 catch e2 == setjmp • the context (callee-saved registers, e2’s code label, etc.) is saved • the context is also called a handler • throw == longjmp • fetch the handler, restore machine states and jump to the handler’s code • “Try” can be nested, so the handlers are organized in a stack

  12. Machine configuration • M = (C, S, X): • C: code heap • S: operand stack • as we did in the stack-based codegen • X: exception handler stack top xsp

  13. Compiling to setjmp/longjmp C (throw) = jmp [xsp+8] // Essentially the same as // “setjmp”. // To simplify things, we omit the // callee-saved regs here. xsp

  14. Compiling to setjmp/longjmp C (try e1 catch e2) = pushHandler C (e1) popHandler jmp .end .handler restore C (e2) .end xsp

  15. Compiling to setjmp/longjmp C (try e1 catch e2) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (e1) popHandler jmp .end .handler restore C (e2) .end xsp

  16. Compiling to setjmp/longjmp C (try e1 catch e2) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (e1) add xsp, 12 jmp .end .handler restore C (e2) .end xsp

  17. Compiling to setjmp/longjmp C (try e1 catch e2) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (e1) add xsp, 12 jmp .end .handler mov top, [xsp+4] add xsp, 12 C (e2) .end xsp

  18. Example #1 C (try 3 catch 5) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (3) add xsp, 12 jmp .end .handler mov top, [xsp+4] add xsp, 12 C (5) .end ### 3 top xsp

  19. Example #1 C (try 3 catch 5) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (3) add xsp, 12 jmp .end .handler mov top, [xsp+4] add xsp, 12 C (5) .end ### 3 top xsp

  20. Example #1 C (try 3 catch 5) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (3) add xsp, 12 jmp .end .handler mov top, [xsp+4] add xsp, 12 C (5) .end ### 3 top xsp

  21. Example #2 C (try throw catch 5) = sub xsp, 12 mov [xsp+4], top mov [xsp+8], .handler C (throw) add xsp, 12 jmp .end .handler mov top, [xsp+4] add xsp, 12 C (5) .end // Rest leave to you! ### top xsp

  22. Moral • Relatively easy to implement • C++ compilers use this scheme, e.g. VC • the exception handler stack can be combined with operand stack (and even with the implicit control stack) • Disadvantage: • performance penalty at each “try”

  23. Table-driven approach C (try e1 catch e2) = .L1: C (e1) jmp .L3 .L2 C (e2) .L3 C (throw) = search_table

  24. Table-driven approach • Compilers produce an exception table, which is referred to when an exception is raised • based on the value of current “eip” • Normal execution can proceed at full speed

  25. Example #1 C (try 3 catch 5) = .L1 C (3) jmp .L3 .L2 C (5) .L3

  26. Example #2 C (try throw catch 5) = .L1 C (throw) jmp .L3 .L2 C (5) .L3

  27. Moral • Table-driven scheme has no cost with normal execution • exceptions are exceptional, pay as you go • JVM uses this scheme • Disadvantage: • exception table takes space

More Related