93
A Java Compiler Overview

A Java Compiler Overview. October 21, 2003Shane A. Brewer2 Who Am I? Shane A. Brewer [email protected] brewer Masters Graduate

Embed Size (px)

Citation preview

A Java Compiler Overview

October 21, 2003 Shane A. Brewer 2

Who Am I? Shane A. Brewer [email protected] http://www.cs.ualberta.ca/~brewer Masters Graduate Student Supervisor: Dr. Nelson Amaral Research: Using Method Specialization In Java

Virtual Machines for Method Devirtualization Member of the U of A Swim Team NOTE: Presentation Slides will be made

available via my web site.

October 21, 2003 Shane A. Brewer 3

This Lecture…

Will give an overview of the Java Environment.

Discuss the differences in how compiler optimizations are applied compared with other languages (C, C++, etc)

Will give an overview of a toolset developed specifically for Java (Soot)

October 21, 2003 Shane A. Brewer 4

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration

October 21, 2003 Shane A. Brewer 5

Java History First release of Java in 1996 by Sun Microsystems The Java Language Specification by James Gosling

published in 1996 The Java Virtual Machine Specification by Tim

Lindholm and Frank Yelle published in 1996 Is now one of the most popular programming

languages, especially in enterprise development. Java 1.5 to be released late 2003 and will include:

Auto Boxing/Unboxing Enhanced For loops Generics (Templates) Enumerations

October 21, 2003 Shane A. Brewer 6

Java Overview Is an object-oriented language that is

executed on a virtual machine Originally designed for Internet-based

usage Combines procedural and object-oriented

features Combines primitive data types and objects Originally designed to be very portable Strongly Typed Supports Dynamic Class Loading Built-in support for multi-threading

October 21, 2003 Shane A. Brewer 7

Java Environment [6]

October 21, 2003 Shane A. Brewer 8

Java Overview Continued

Java Source Files

Java Classfiles

int d = 2 + 3;object.foo();

Java BytecodeCompiler

i_const2i_const3

iaddinvokevirtual #40

Java VirtualMachine

i0 := 2;i1 := 3;

i2 := i0 + i2;java.lang.Object.foo();

lw $s1, 100($s2)add $s1, $s2, $s3

Compiler IntermediateRepresentation

Executable MachineCode

October 21, 2003 Shane A. Brewer 9

The Java Platform [6]

October 21, 2003 Shane A. Brewer 10

A Java Program

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else } // End method stepPoly} // End class javaTest

class javaTest { public static void main(String[] args) { int x = stepPoly(6); System.out.println(x); } // End method main

October 21, 2003 Shane A. Brewer 11

Dynamic Class Loading Allows a new class to be loaded into the class

hierarchy at any point in execution 2 Ways This Is Done In Java

Class.forName() method gets the runtime class descriptor

Class toRun = Class.forName(args[0]); User-defined Class Loaders allows a user to load

classes in custom ways (across a network, local, etc) Good for program design

Lazy class loading Dynamic installation of software

Bad for optimization

October 21, 2003 Shane A. Brewer 12

Dynamic Class Loading Example

Class A {public void func() {

foo(); bar();

}public void foo() {}public void bar() {}

} // End Class A

Class B extends A {…

} // End Class B

Can we make theseMethod calls static?

October 21, 2003 Shane A. Brewer 13

Dynamic Class Loading Example

Class A {public void func() {

A.foo(); A.bar();

}public void foo() {}public void bar() {}

} // End Class A

Class B extends A {…

} // End Class B

Can we make theseMethod calls static?

October 21, 2003 Shane A. Brewer 14

Dynamic Class Loading Example

Class A {public void func() {

A.foo(); A.bar();

public void foo() {}public void bar() {}}

} // End Class A

Class B extends A { …} // End Class B

Class C extends B {public void foo() {}public void bar() {}

} // End Class C

No! A class of type C can be loadedat any point in program execution.Consider an object objC of type C.

A method call objC.func() would resultin A.foo() and A.bar() incorrectly

being called.

WRONG!!!

October 21, 2003 Shane A. Brewer 15

Differences Between C++ and Java Java is run by a virtual machine Java does not contain pointers (YAY!) Java does not support generics (Will be

supported in version 1.5) Java does not contain a preprocessor Java only allows single inheritance.

Interfaces can be used to remedy this. Java contains built-in multi-threaded

tools.

October 21, 2003 Shane A. Brewer 16

Problems With Java Relatively Slow execution?

Compilation done at run-time Run-time exception checking Optimizations have to deal with dynamic class

loading Slow execution can be offset by spending time

optimizing “hot” portions of code Not pure object-oriented No Generics (Version 1.5) Everything is a reference No const method arguments

October 21, 2003 Shane A. Brewer 17

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration

October 21, 2003 Shane A. Brewer 18

The Java Bytecode Compiler Converts Java source code to Java bytecode

and into Class files Can be thought of a the “front end” of a

traditional compiler Can perform a limited set of optimizations Optimizations are harder to perform because:

Some bytecode instructions are high-level Dynamic class loading

Examples: Sun Microsystems: javac IBM: Jikes

October 21, 2003 Shane A. Brewer 19

Java Bytecodes Defined by the Java Virtual Machine

Instruction Set. Are stack based

Keeps the instruction set compact Facilitates implementation on architectures

with few or irregular registers. Most of the operators are typed

iadd (Adds 2 integers together) Some operators are not typed

dup (Duplicates the top value on the stack)

October 21, 2003 Shane A. Brewer 20

The Class file Are not limited to the Java programming

language Is a file containing :

Java bytecodes a definition of a single class or interface

Contains everything a JVM needs to know about the particular class or interface.

Are strictly defined so JVM know what to expect Are variable length Contains 3 major parts:

Identification Constant Pool Detailed Information

October 21, 2003 Shane A. Brewer 21

October 21, 2003 Shane A. Brewer 22

A Java Program

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static void main(String[] args) { int x = stepPoly(6); System.out.println(x);} // End method main

October 21, 2003 Shane A. Brewer 23

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

To obtain a listing of the bytecode froma classfile, use the command:

javap –c <classfile>

October 21, 2003 Shane A. Brewer 24

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

-Pushes an integer located at local variable index 0 on the stack (the firstparameter to the method “x”)-Sees if x (position 14 in the constantpool) is greater than 0

October 21, 2003 Shane A. Brewer 25

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

-Pushes the receiver object System.outon to the stack.-Pushes the parameter to the method(String “Bad Argument) on the stack-Invokes the virtual method

October 21, 2003 Shane A. Brewer 26

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

-Pushes literal -1 on the stack-Returns from the function with an integer

October 21, 2003 Shane A. Brewer 27

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

-Pushes integer from local variable atindex 0 (first parameter to the method)-Pushes the constant 5 on the stack-Compares the 2 values on the stack andjumps to line 23 if x is greater than 5.

October 21, 2003 Shane A. Brewer 28

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

-Load x on the stack (twice)-Execute an integer multiplication and push the result on the stack-Return the result

October 21, 2003 Shane A. Brewer 29

Java Bytecode

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

-Push x on the stack-Push 5 on the stack-Multiply the values and push the resulton the stack-Push 16 on the stack-Add the values and push the result-Return the integer on the stack

October 21, 2003 Shane A. Brewer 30

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration

October 21, 2003 Shane A. Brewer 31

The Java Virtual Machine Is an abstract computing machine Only takes class files as input Executes the corresponding bytecodes on the computer

architecture Techniques are left up to the VM implementer:

Compilation Optimization Memory Management Object Layout

Examples: Sun Microsystems: Hot Spot IBM: Jikes RVM Blackdown: Blackdown VM (Linux)

October 21, 2003 Shane A. Brewer 32

Bytecode Translation Methods Interpreted

Stack based Done one bytecode at a time SLOW!

Just-In-Time (JIT) Bytecodes are compiled to native machine

instructions when they are executed. Compilation only done once Optimizations can take advantage of run-time

profiling Optimizations must be done during execution,

making high cost optimizations unattractive

October 21, 2003 Shane A. Brewer 33

Bytecode Translation Methods Continued Adaptive Just-In-Time

Similar to JIT compilers Performs dynamic analysis to determine “hot”

portions of code and perform higher levels of optimization

Can also use analysis to determine which optimizations will obtain the greatest speedup

Compilation can be done multiple times Ahead-of-time (Way-Ahead-of-Time)

Compilation to native machine code is done by the bytecode compiler, just like C++

Allows high cost optimizations to be performed Portability is lost Dynamic Class Loading is not permitted

October 21, 2003 Shane A. Brewer 34

Stack-based InterpretationLocal Variables Array

6

Stack

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Entering method stepPolyfrom call site:

int x = stepPoly(6);

October 21, 2003 Shane A. Brewer 35

Stack-based InterpretationLocal Variables Array

6

Stack

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pushes the integer locatedat index 0 in the local

variable array on the stack

October 21, 2003 Shane A. Brewer 36

Stack-based InterpretationLocal Variables Array

6

Stack

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pops the stack and determines if the value isgreater than or equal to 0.If true, jump to the index

in the byte array.

October 21, 2003 Shane A. Brewer 37

Stack-based InterpretationLocal Variables Array

6

Stack

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pops the stack and determines if the value isgreater than or equal to 0.If true, jump to the index

in the byte array.

6 < 0?

October 21, 2003 Shane A. Brewer 38

Stack-based InterpretationLocal Variables Array

6

Stack

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pops the stack and determines if the value isgreater than or equal to 0.If true, jump to the index

in the byte array.

October 21, 2003 Shane A. Brewer 39

Stack-based InterpretationLocal Variables Array

6

Stack

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pushes the integer locatedat index 0 in the local

variable array on the stack

October 21, 2003 Shane A. Brewer 40

Stack-based InterpretationLocal Variables Array

6

Stack

5

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pushes the integer constant5 on the stack

October 21, 2003 Shane A. Brewer 41

Stack-based InterpretationLocal Variables Array

6

Stack

5

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

The top 2 values on the stack are popped and compared. If value 1 is

greater than value 2, controltransfers to the specifiedindex in the byte array.

October 21, 2003 Shane A. Brewer 42

Stack-based InterpretationLocal Variables Array

6

Stack

5 (Value 2)

6 (Value 1)

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

The top 2 values on the stack are popped and compared. If value 1 is

greater than value 2, controltransfers to the specifiedindex in the byte array.

Is 6 < 5?

October 21, 2003 Shane A. Brewer 43

Stack-based InterpretationLocal Variables Array

6

Stack

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

The top 2 values on the stack are popped and compared. If value 1 is

greater than value 2, controltransfers to the specifiedindex in the byte array.

Is 6 < 5?

October 21, 2003 Shane A. Brewer 44

Stack-based InterpretationLocal Variables Array

6

Stack

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pushes the integer locatedat index 0 in the local

variable array on the stack

October 21, 2003 Shane A. Brewer 45

Stack-based InterpretationLocal Variables Array

6

Stack

5

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pushes the integer constant5 on the stack

October 21, 2003 Shane A. Brewer 46

Stack-based InterpretationLocal Variables Array

6

Stack

5

6

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top 2 values off ofthe stack. Multiply themtogether and push the

result on the stack

October 21, 2003 Shane A. Brewer 47

Stack-based InterpretationLocal Variables Array

6

Stack

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top 2 values off ofthe stack. Multiply themtogether and push the

result on the stack

5 * 6 = 30

October 21, 2003 Shane A. Brewer 48

Stack-based InterpretationLocal Variables Array

6

Stack

30

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top 2 values off ofthe stack. Multiply themtogether and push the

result on the stack

5 * 6 = 30

October 21, 2003 Shane A. Brewer 49

Stack-based InterpretationLocal Variables Array

6

Stack

30

16

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Push the immediate byte(an integer) on to the stack.

October 21, 2003 Shane A. Brewer 50

Stack-based InterpretationLocal Variables Array

6

Stack

30

16

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top 2 values fromthe stack, add them

together, and push the result on the stack.

October 21, 2003 Shane A. Brewer 51

Stack-based InterpretationLocal Variables Array

6

Stack

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top 2 values fromthe stack, add them

together, and push the result on the stack.

30 + 16 = 46

October 21, 2003 Shane A. Brewer 52

Stack-based InterpretationLocal Variables Array

6

Stack

46

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top 2 values fromthe stack, add them

together, and push the result on the stack.

30 + 16 = 46

October 21, 2003 Shane A. Brewer 53

Stack-based InterpretationLocal Variables Array

6

Stack

46

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Pop the top value from thestack from this method frame,and push the value on to thestack of the caller method’sstack. Any other values on

the stack are discarded.

October 21, 2003 Shane A. Brewer 54

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration

October 21, 2003 Shane A. Brewer 55

What Is Soot? A Java bytecode compiler written in

Java Includes decompilation and

visualization Used to analyze and transform Java

bytecode Comes as a command line tool or

Eclipse plugin Output is an optimized class file

October 21, 2003 Shane A. Brewer 56

October 21, 2003 Shane A. Brewer 57

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration

October 21, 2003 Shane A. Brewer 58

Soot Intermediate Representations (IRs) Baf: A stack representation without the

complexities of Java bytecode. Jimple: A typed, 3-address code

representation of Java bytecode (Java Simple)

Shrimple: An SSA-version of Jimple Grimp: Like Jimple, but with aggregated

expressions. Dava: A structured representation

suitable for Decompiling Java

October 21, 2003 Shane A. Brewer 59

Soot Intermediate Representations

October 21, 2003 Shane A. Brewer 60

Baf: In Depth

Analysis and transformations on Java bytecode is problematic for 2 reasons: Encoding Issues Untyped Bytecodes

A stack based representation Easier to manipulate as it is fully

typed

October 21, 2003 Shane A. Brewer 61

Previous Example

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static void main(String[] args) { int x = stepPoly(6); System.out.println(x);} // End method main

Refer back to our Java example

October 21, 2003 Shane A. Brewer 62

Previous Example

public static int stepPoly(int x) { if(x < 0) { System.out.println("Bad Argument"); return -1; } else if (x <= 5) { return x * x; } else { return x * 5 + 16; } // End if-else} // End method stepPoly

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

Java method with correspondingbytecode

October 21, 2003 Shane A. Brewer 63

Bytecode and Corresponding Baf

public static int stepPoly(int); Code: 0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn 14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

public static int stepPoly(int) { word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream: void println(java.lang.String)>; push -1; return.i;

label0: load.i i0; push 5; ifcmpgt.i label1;

load.i i0; load.i i0; mul.i; return.i;

label1: load.i i0; push 5; mul.i; push 16; add.i; return.i; }

October 21, 2003 Shane A. Brewer 64

Bytecode and Corresponding Baf: Broken Up

0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

The baf file starts off with variable declarations. A prefix of “r” refers to a generalpurpose variable while an “i” refers a variable that stores an integer.

October 21, 2003 Shane A. Brewer 65

Bytecode and Corresponding Baf: Broken Up

0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

-The first instruction takes the first parameter to the method and stores it in variable i0.

-The second instruction loads in the value of variable i0 and push it on the stack.

October 21, 2003 Shane A. Brewer 66

Bytecode and Corresponding Baf: Broken Up

0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

-Here, the if-greater-than-or-equal is replaced by a label, rather than an index intothe bytecode array. Note that the label is not shown in this snippet.

October 21, 2003 Shane A. Brewer 67

Bytecode and Corresponding Baf: Broken Up

0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

-The first instruction obtains the receiver object of the static method “java.io.PrintStream.println”. Here, the receiver object is the class

“java.lang.System.out” where the type of “out” is “java.io.PrintStream”.-The second instruction pushes the first argument to the method on the stack. In

this case it is the string “Bad Argument”.-The last instruction invokes the virtual method “java.io.PrintStream” with a return

value of void, and a single argument of type “java.lang.String”

October 21, 2003 Shane A. Brewer 68

Bytecode and Corresponding Baf: Broken Up

0: iload_0 1: ifge 14 4: getstatic #25; //Field java/lang/System.out:

Ljava/io/PrintStream; 7: ldc #37; //String Bad Argument 9: invokevirtual #40; //Method java/io/PrintStream.println:

(Ljava/lang/String;)V 12: iconst_m1 13: ireturn

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

-The constant -1 is pushed on to the stack-The method exits, returning a integer located on the top of the stack

October 21, 2003 Shane A. Brewer 69

Bytecode and Corresponding Baf

-Targets of gotos are specifically labeled in Baf

14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

label0: load.i i0; push 5; ifcmpgt.i label1; load.i i0; load.i i0; mul.i; return.i; label1: load.i i0; push 5; mul.i; push 16; add.i; return.i;

October 21, 2003 Shane A. Brewer 70

Bytecode and Corresponding Baf

-An integer (The first argument to the method) is pushed on the stack. Remember thatwe stored the first argument into variable i0 in the previous snippet.

-The constant 5 is pushed on the stack-A comparison of the top 2 values on the stack are compared. Note the difference

between the target of the gotos if the test succeeds.

14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

label0: load.i i0; push 5; ifcmpgt.i label1; load.i i0; load.i i0; mul.i; return.i; label1: load.i i0; push 5; mul.i; push 16; add.i; return.i;

October 21, 2003 Shane A. Brewer 71

Bytecode and Corresponding Baf

14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

label0: load.i i0; push 5; ifcmpgt.i label1; load.i i0; load.i i0; mul.i; return.i; label1: load.i i0; push 5; mul.i; push 16; add.i; return.i;

-The first argument is pushed on to the stack twice (not much difference)-Integer multiplication is performed

-The top value on the stack (an integer) is returned

October 21, 2003 Shane A. Brewer 72

Bytecode and Corresponding Baf

14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

label0: load.i i0; push 5; ifcmpgt.i label1; load.i i0; load.i i0; mul.i; return.i; label1: load.i i0; push 5; mul.i; push 16; add.i; return.i;

-Argument is loaded again-The constant 5 is pushed on the stack

-Integer multiplication is done. Result is pushed on the stack

October 21, 2003 Shane A. Brewer 73

Bytecode and Corresponding Baf

14: iload_0 15: iconst_5 16: if_icmpgt 23 19: iload_0 20: iload_0 21: imul 22: ireturn 23: iload_0 24: iconst_5 25: imul 26: bipush 16 28: iadd 29: ireturn

label0: load.i i0; push 5; ifcmpgt.i label1; load.i i0; load.i i0; mul.i; return.i; label1: load.i i0; push 5; mul.i; push 16; add.i; return.i;

-The constant 16 is pushed on the stack-Integer addition is performed on the top 2 values on the stack

-The method returns the top value on the stack (An integer)

October 21, 2003 Shane A. Brewer 74

Jimple: In Depth Optimizing stack code is awkward

Expression are not explicit; An instruction may have it’s operands separated by an arbitrary number of stack instructions

Stack is untyped by nature Jimple is a 3-address code representation of

bytecode Typed Is ideal for performing optimizations and

analysis Operators are untyped Local variables are given explicit primitive,

class, or interface types

October 21, 2003 Shane A. Brewer 75

Baf and Corresponding Jimple

public static int stepPoly(int) { word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream: void println(java.lang.String)>; push -1; return.i;

label0: load.i i0; push 5; ifcmpgt.i label1;

load.i i0; load.i i0; mul.i; return.i;

label1: load.i i0; push 5; mul.i; push 16; add.i; return.i; }

public static int stepPoly(int) { int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

label0: if i0 > 5 goto label1;

$i1 = i0 * i0; return $i1;

label1: $i2 = i0 * 5; $i3 = $i2 + 16; return $i3; }

October 21, 2003 Shane A. Brewer 76

Baf and Corresponding Jimple

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

-Variable declarations come first. In Jimple, variables prefixed with a “$” refer to a stack position.

-Variables i0, $i1, $i2, $i3 are typed as integers.-Variable $r0 is typed as java.io.PrintStream

October 21, 2003 Shane A. Brewer 77

Baf and Corresponding Jimple

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

-Variable i0 gets the value of the first parameter to the method.-The if check is reduced to a single instruction, compared with 2 stack-based instructions.

Goto and labels remain the same.

October 21, 2003 Shane A. Brewer 78

Baf and Corresponding Jimple

word i0;

i0 := @parameter0: int; load.i i0; ifge label0;

staticget <java.lang.System: java.io.PrintStream out>; push "Bad Arugument"; virtualinvoke <java.io.PrintStream:

void println(java.lang.String)>; push -1; return.i;

int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

-The receiver of the method call “java.io.PrintStream” is stored in variable $r0. Notethat in Baf, this was a stack position.

-The virtual method “println” is invoked on the object stored in $r0.-The constant -1 is returned from the method.

October 21, 2003 Shane A. Brewer 79

Baf and Corresponding Jimple

label0: load.i i0; push 5; ifcmpgt.i label1;

load.i i0; load.i i0; mul.i; return.i;

label1: load.i i0; push 5; mul.i; push 16; add.i; return.i; }

label0: if i0 > 5 goto label1;

$i1 = i0 * i0; return $i1;

label1: $i2 = i0 * 5; $i3 = $i2 + 16; return $i3;

-The if statement is reduced from 3 Baf instructions to 1 Jimple instruction.

October 21, 2003 Shane A. Brewer 80

Baf and Corresponding Jimple

label0: load.i i0; push 5; ifcmpgt.i label1;

load.i i0; load.i i0; mul.i; return.i;

label1: load.i i0; push 5; mul.i; push 16; add.i; return.i; }

label0: if i0 > 5 goto label1;

$i1 = i0 * i0; return $i1;

label1: $i2 = i0 * 5; $i3 = $i2 + 16; return $i3;

-The multiplication operation is no longer typed in Jimple.-The variable $i1 refers to the result of the multiplication operation that was a stack

position.

October 21, 2003 Shane A. Brewer 81

Baf and Corresponding Jimple

label0: load.i i0; push 5; ifcmpgt.i label1;

load.i i0; load.i i0; mul.i; return.i;

label1: load.i i0; push 5; mul.i; push 16; add.i; return.i; }

label0: if i0 > 5 goto label1;

$i1 = i0 * i0; return $i1;

label1: $i2 = i0 * 5; $i3 = $i2 + 16; return $i3;

-The results of the multiplication and addition operations are stored in the $i2 and $i3variables. These are stack positions in Baf.

October 21, 2003 Shane A. Brewer 82

Grimp: In Depth 3 address code is sometimes harder to

deal with than complex structures. Generating stack code is simpler with large

expressions. Grimp is an unstructured representation

which allows trees to be constructed for expressions.

Easy to read Used for the foundation of a decompiler. Similar to the original Java code.

October 21, 2003 Shane A. Brewer 83

Jimple and Corresponding Grimp

public static int stepPoly(int) { int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

label0: if i0 > 5 goto label1;

$i1 = i0 * i0; return $i1;

label1: $i2 = i0 * 5; $i3 = $i2 + 16; return $i3; }

public static int stepPoly(int) { int i0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

<java.lang.System: java.io.PrintStream out>.<java.io.PrintStream: void println(java.lang.String)>("Bad Arugument");

return -1;

label0: if i0 > 5 goto label1;

return i0 * i0;

label1: return i0 * 5 + 16; }

October 21, 2003 Shane A. Brewer 84

Jimple and Corresponding Grimp

int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

int i0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

<java.lang.System: java.io.PrintStream out>.<java.io.PrintStream: void println(java.lang.String)>("Bad Arugument");

return -1;

-Only one variable is needed as the operations are aggregated together.

October 21, 2003 Shane A. Brewer 85

Jimple and Corresponding Grimp

int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

int i0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

<java.lang.System: java.io.PrintStream out>.<java.io.PrintStream: void println(java.lang.String)>("Bad Arugument");

return -1;

-These instructions stay the same.

October 21, 2003 Shane A. Brewer 86

Jimple and Corresponding Grimp

int i0, $i1, $i2, $i3; java.io.PrintStream $r0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

$r0 = <java.lang.System: java.io.PrintStream out>; virtualinvoke $r0.<java.io.PrintStream:

void println(java.lang.String)>("Bad Arugument"); return -1;

int i0;

i0 := @parameter0: int; if i0 >= 0 goto label0;

<java.lang.System: java.io.PrintStream out>.<java.io.PrintStream: void println(java.lang.String)>("Bad Arugument");

return -1;

-The receiver object “java.lang.System.out” is hard coded in the method call instructionalong with the argument.

October 21, 2003 Shane A. Brewer 87

Jimple and Corresponding Grimp

label0: if i0 > 5 goto label1;

$i1 = i0 * i0; return $i1;

label1: $i2 = i0 * 5; $i3 = $i2 + 16; return $i3;

label0: if i0 > 5 goto label1;

return i0 * i0;

label1: return i0 * 5 + 16;

-Instructions are aggregated together into a single instruction.

October 21, 2003 Shane A. Brewer 88

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration

October 21, 2003 Shane A. Brewer 89

Soot Optimizations Common Subexpression Elimination Busy Code Motion Lazy Code Motion Copy Propagation Constant Propagation Dead Assignment Elimination Unreachable Code Elimination Unconditional Branch Folding

October 21, 2003 Shane A. Brewer 90

Soot Perfomance Changing bytecode to Baf, then Jimple, the

Grimp, and then back to Bytecode with no optimizations reduces performance by only 2%.

With whole program optimizations turned on, speedups of 21% were found for SPECjvm98.

Using the attributes extension, programs exhibited speedups of approximately 8% (Some with slowdown)

October 21, 2003 Shane A. Brewer 91

Summary

Java offers new challenges for compilers at both the classfile level and the virtual machine level.

Soot offers a set of tools to optimize classfiles.

Will Java become faster than other languages? (C, C++, etc)

October 21, 2003 Shane A. Brewer 92

References1. http://www.sable.mcgill.ca/soot2. http://www.eclipse.org3. P. Pominville, F. Qian, R. Vallee-Rai, L. Hendren, and C.

Verbrugge, “A Gramework For Optimizing Java Using Attributes”, Lecture Notes In Computer Science, 2001.

4. R. Vallee-Rai, P. Co, E. Gagnon, L. Hendren, P. Lam, and V. Sundaresan, “Soot – A Java Bytecode Optimization Framework”, Proceedings of CASCON '99, 1999.

5. R. Vallee-Rai, E. Gagnon, L. Hendren, P. Lam, P. Pominville, and V. Sundaresan, “Optimizing Java Bytecode Using The Soot Gramework: Is It Feasible?”, Computational Complexity, 2000.

6. Bill Venners, “Inside the Java 2 Virtual Machine”, McGraw-Hill Osborne Media, 2000.

October 21, 2003 Shane A. Brewer 93

Outline A Brief Java Overview Java Bytecode, Class files, and Bytecode

Compilers Java Virtual Machines and Compilation

Techniques Soot Overview Soot Intermediate Representations Soot Optimizations and Performance Soot Eclipse Plugin Demonstration