1 / 34

Compilation 2007 Code Generation

Compilation 2007 Code Generation. Michael I. Schwartzbach BRICS, University of Aarhus. Code Generation Phases. Computing resources, such as: layout of data structures offsets register allocation Generating an internal representation of machine code for statements and expressions

jadon
Télécharger la présentation

Compilation 2007 Code Generation

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. Compilation 2007Code Generation Michael I. Schwartzbach BRICS, University of Aarhus

  2. Code Generation Phases • Computing resources, such as: • layout of data structures • offsets • register allocation • Generating an internal representation of machine code for statements and expressions • Optimizing the generated code (ignored for now) • Emitting the code to files in assembler format • Assembling the emitted code to binary format Code Generation

  3. Joos Code Generation • Compute offsets and signatures • Generate code for static initializers • Generate code for statements and expressions • Optimize the generated code (ignored for now) • Compute locals and stack limits • Emit Jasmin code • Assemble Jasmin code to class files Code Generation

  4. Computing Offsets • Each formal and local variables must have an offset in the stack frame • The this object always has offset 0 • The naive solution: • enumerate all formals and locals • The better solution: • reuse offsets for locals in disjoint scopes • The clever solution: • exploit liveness information • must still respect the runtime types of locals Code Generation

  5. Naive Offsets public void m(int p , int q , Object r ) int x = 42; int y ; { int z ; z = 87; } { boolean a ; Object b ; { boolean b ; int z ; b = true; boolean c ; c = b && (x==87); } { int y ; y = x; } } } 1 2 3 4 5 6 7 8 9 max = 12 10 11 12 Code Generation

  6. Better Offsets public void m(int p , int q , Object r ) int x = 42; int y ; { int z ; z = 87; } { boolean a ; Object b ; { boolean b ; int z ; b = true; boolean c ; c = b && (x==87); } { int y ; y = x; } } } 1 2 3 4 5 6 6 7 8 max = 10 9 10 8 Code Generation

  7. Clever Offsets public void m(int p , int q , Object r ) int x = 42; int y ; { int z ; z = 87; } { boolean a ; Object b ; { boolean b ; int z ; b = true; boolean c ; c = b && (x==87); } { int y ; y = x; } } } 1 2 3 4 4 5 6 3 6 max = 6 5 6 5 Code Generation

  8. Computing Signatures (1/2) • The function sig(σ) encodes a type: sig(void) = V sig(byte) = B sig(short) = S sig(int) = I sig(char) = C sig(boolean) = Z sig(σ[]) = [desc(σ) sig(C1.C2. ... .Ck) = C1/C2/.../Ck desc(void) = V desc(byte) = B desc(short) = S desc(int) = I desc(char) = C desc(boolean) = Z desc(σ[]) = [desc(σ) desc(C1.C2. ... .Ck) = LC1/C2/.../Ck; Code Generation

  9. Computing Signatures (2/2) • This extends to fields, methods, and constructors • The field named x in class C: sig(C)/x • The method σ m(σ1 x1, ..., σk xk) in class C: sig(C)/m(desc(σ1)...desc(σk))desc(σ) • The constructor C(σ1 x1, ..., σk xk) in class C: sig(C)/<init>(desc(σ1)...desc(σk))V Code Generation

  10. Static Initializers (1/2) • Initialization of static fields is performed when the class is loaded by the JVM • All static fields are first given default values • The code for initialization is written in a special method with the name <clinit> • Fields that are staticfinal and constant valued must then be initialized • Finally, all other static fields are initialized Code Generation

  11. Static Initializers (2/2) public class A { public static int x = A.y+1; public static final int y = 42; public static void main(String[] args) { System.out.print(A.x); } } 43 public class A { public static int x = A.y+1; public static int y = 42; public static void main(String[] args) { System.out.print(A.x); } } 1 public class A { public static int x = A.y+1; public static final int y = A.fortytwo(); public static int fortytwo() { return 42; } public static void main(String[] args) { System.out.print(A.x); } } 1 Code Generation

  12. Generating Code • Each statement and expression generates a sequence of bytecodes • A code template shows how to generate bytecodes for a given language construct • The template ignores the surrounding context • This yields a simple, recursive strategy for the code generation Code Generation

  13. Code Template Invariants • A statement and a void expression leaves the stack height unchanged • A non-void expression increases the stack height by one • This is a local property of each template • The generated code must be verifiable • This is not a local property, since the verifier performs a global static analysis Code Generation

  14. Code Templates (1/12) if(E) S1else S2 E ifeq false S1 goto endif false: S2 endif: nop if(E) S E ifeq false S false: while(E) S goto cond: loop: S cond: E ifne loop while(true) S loop: S goto loop Code Generation

  15. Code Templates (2/12) { σn = E; S } E σstoreoffset(n) S σstore is either istore or astore depending on σ { σn; S } S E; E E; E pop type(E) = void type(E) ≠void return E; E σreturn throw E; E athrow return;return Code Generation

  16. Code Templates (3/12) new C(E1,...,Ek) @ δnew sig(C) dup E1 ... Ek invokespecial sig(δ) this(E1,...,Ek) @ δaload 0 E1 ... Ek invokespecial sig(δ) @ δ indicates that δ is the corresponding resolved declaration Code Generation

  17. Code Templates (4/12) super(E1,...,Ek) @ δaload 0 E1 ... Ek invokespecial sig(δ) aload 0 I1 putfield sig(x1) desc(σ1) ... aload 0 In putfield sig(xn) desc(σn) The current class contains the non-static field initializations: σ1 x1 = I1; ... σn xn = In; Code Generation

  18. Code Templates (5/12) E.m(E1,...,Ek) @ δ E E1 ... Ek invokevirtual sig(δ) sig(δ) is a class E.m(E1,...,Ek) @ δ E E1 ... Ek invokeinterface sig(δ) sig(δ) is an interface C.m(E1,...,Ek) @ δ E1 ... Ek invokestatic sig(δ) Code Generation

  19. Code Templates (6/12) (C)E E checkcast sig(C) (char)E E i2c E instanceof C E instanceof sig(C) Code Generation

  20. Code Templates (7/12) this aload 0 nσload offset(n) type(n) = σ E.fE getfield sig(f) desc(type(E.f)) C.f getstatic sig(f) desc(type(C.f)) E1[E2] E1 E2 σaload σaload is either iaload, baload, saload, caload, or aaload depending on σ type(E1[E2]) = σ Code Generation

  21. Code Templates (8/12) n = EE dup σstore offset(n) type(n) = σ E1.f = E2E1 E2 dup_x1 putfield sig(f) desc(type(E1.f)) C.f = EE dup putstatic sig(f) desc(type(C.f)) E1[E2]= E3E1 E2 E3 dup_x2 σastore type(E1[E2]) = σ Code Generation

  22. Code Templates (9/12) newσ[E]E multianewarray desc(σ) 1 E.lengthE arraylength E.clone() E invokevirtual sig(type(E))/clone()Ljava/lang/Object; Code Generation

  23. Code Templates (10/12) 42 ldc_int 42 true ldc_int 1 null aconst_null "abc" ldc_string "abc" Code Generation

  24. Code Templates (11/12) E1+ E2E1 E2 iadd type(E1+E2) = int E1+ E2E1 E2 invokevirtual S/concat(LS;)LS; type(E1+E2) = String S java/lang/String - E E ineg Code Generation

  25. Code Templates (12/12) E1|| E2E1 dup ifne firsttrue pop E2 firsttrue: E1&& E2E1 dup ifeq firstfalse pop E2 firstfalse: Code Generation

  26. Stack and Locals Limits • The generated code must explicitly state: • the maximal number of local and formal offsets • the maximal local stack height • This is used to determine the size of the frame • The locals limit is the maximal offset + (1 or 0) • The stack limit is computed by a static analysis Code Generation

  27. Stack Limit Analysis • Consider the control flow graph of the bytecodes • succ(Si) denotes the set of successor bytecodes • Δ(Si) denotes the change in stack height by Si • S0 denotes the first bytecode • For every bytecode Si we define the following integer-valued properties: • B[[Si]] denotes the stack height before Si • A[[Si]] denotes the stack height after Si Code Generation

  28. Dataflow Constraints • B[[S0]] = 0 • A[[Si]] = B[[Si]] + Δ(Si) • xsucc(Si): A[[Si]] = B[[x]] • A[[Si]]  0 • These constraints must have a solution • The stack limit is the largest value of any A[[Si]] Code Generation

  29. Jasmin Class Format (1/3) • The overall structure of a Jasmin file is: .source sourcefile .class modifiers name .super sig(superclass) .implements sig(interface) .field modifiersdesc(type) constructors methods Code Generation

  30. Jasmin Class Format (2/3) • The structure of a constructor is: .method modifierssig(constructor) .throws sig(exception) .limit stack stacklimit .limit locals localslimit bytecodes .end method Code Generation

  31. Jasmin Class Format (3/3) • The structure of a method is: .method modifierssig(method) .throws sig(exception) .limit stack stacklimit .limit locals localslimit bytecodes .end method Code Generation

  32. A Tiny Class public class Foo { public int y = 42; public Foo(int z) { y = y+z; } public String print(int n) { if (n==0) return new Integer(y).toString(); else return new Foo(y).print(n-1); } } Code Generation

  33. The Generated Code .source Foo.java .class public Foo .super java/lang/Object .field public "y" I .method public <init>(I)V .limit stack 3 .limit locals 2 aload_0 invokespecial java/lang/Object/<init>()V aload_0 bipush 42 putfield Foo/y I aload_0 aload_0 getfield Foo/y I iload_1 iadd dup_x1 putfield Foo/y I pop return .end method .method public print(I)Ljava/lang/String; .limit stack 3 .limit locals 2 iload_1 iconst_0 if_icmpeq true2 iconst_0 goto end3 true2: iconst_1 end3: ifeq false0 new java/lang/Integer dup aload_0 getfield Foo/y I invokespecial java/lang/Integer/<init>(I)V invokevirtual java/lang/Integer/toString()Ljava/lang/String; areturn false0: new Foo dup aload_0 getfield Foo/y I invokespecial Foo/<init>(I)V iload_1 iconst_1 isub invokevirtual Foo/print(I)Ljava/lang/String; areturn .end method Code Generation

  34. The Binary Class File cafe babe 0000 002e 001e 0c00 0a00 1901 0011 6a61 7661 2f6c 616e 672f 496e 7465 6765 7201 0010 6a61 7661 2f6c 616e 672f 4f62 6a65 6374 0900 0900 1701 0006 3c69 6e69 743e 0700 030c 0005 000d 0100 0346 6f6f 0700 0801 0005 7072 696e 740c 0016 001c 0a00 1d00 1501 0003 2829 5601 0004 436f 6465 0100 0179 0100 0a53 6f75 7263 6546 696c 6501 0001 4901 0004 2849 2956 0a00 0900 010a 0006 0007 0c00 0500 1201 0008 746f 5374 7269 6e67 0c00 0f00 1101 0008 466f 6f2e 6a61 7661 0100 1528 4929 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 0a00 0900 150a 001d 000b 0100 1428 294c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b07 0002 0021 0009 0006 0000 0001 0001 000f 0011 0000 0002 0001 0005 0012 0001 000e 0000 0023 0003 0002 0000 0017 2ab7 0014 2a10 2ab5 0004 2a2a b400 041b 605a b500 0457 b100 0000 0000 0100 0a00 1900 0100 0e00 0000 3a00 0300 0200 0000 2e1b 039f 0007 03a7 0004 0499 0012 bb00 1d59 2ab4 0004 b700 0cb6 001b b0bb 0009 592a b400 04b7 001a 1b04 64b6 0013 b000 0000 0000 0100 1000 0000 0200 1800 Code Generation

More Related