Transcript

Load Time Structural Reflection in Java

Shigeru Chiba

Institute of Information Science and Electronics

University of Tsukuba

Introduction

• Reflection in java– Behavioral reflection– Structural reflection

• Javassist, a class library enabling structural reflection in java

Properties of Javassist

• Portable

• Provides source level abstraction

• Does byte code transformation at compile time

BCA

class Calendar implements Writable {public void write(PrintStream s) { ... }}class Calendar implements Printable {public void write(PrintStream s) { ... }public void print() { write(System.out); }}

• Implementation of BCA with behavioral reflection isnot straightforward

Javassist• Translates alterations by structural reflection into

equivalent bytecode• It is used with a user class loader class MyLoader extends ClassLoader {public Class loadClass(String name) {byte[] bytecode = readClassFile(name);return resolveClass(defineClass(bytecode));}private byte[] readClassFile(String name) {// read a class file from a resource.}}

Javassist API

• A CtClass object has to be created CtClass c = new CtClass(stream or string);

• To obtain bytecode of altered class byte[] bytecode = c.toBytecode();

• Javassist allows to dynamically define a new class CtClass c2 = new CtNewClass();

Introspection

• This part of Javassist is compatible with Java reflection API with the difference that Javassist does not provide methods for creating an instance or invoking a method because these are meaningless at load time

Methods in CtClass for introspecting classes

Alteration by Javassist

• Principles governing alteration in Javassist– Source level abstraction for programmers– Execution of structural reflection efficiently– Type safety while performing Structural

reflection

Adding a new member

void addMethod(CtMethod m, String name, ClassMap map)

void addWrapper(int modifiers, CtClass returnType, String name,CtClass[] parameters, CtClass[] exceptions,CtMethod body, ConstParameter constParam)

Replacing a Class name in the method body

public class XVector extends java.util.Vector {

public void add(X e) {super.addElement(e);}}

CtMethod m = /* method add() in XVector */;CtClass c = /* class StringVector */;ClassMap map = new ClassMap();map.put("X", "java.lang.String");c.addMethod(m, "addString", map);

public void addString(java.lang.String e) {super.addElement(e);}

Altering a Method body

void setBody(CtMethod m, ClassMap map)

void setWrapper(CtMethod m, ConstParameter param)

Reflective class loader

• Javassist provides a reflective class loader which can be used to self-reflectively modify the bytecode

Using Javassist with a Web server

for (;;) {

receive an http request from a web browser.

CtClass c = new CtClass(the requested class); do structural reflection on c if needed.

byte[] bytecode = c.toBytecode();

send the bytecode to the web browser.

}

Using Javassist Off line

CtClass c =newCtClass("Rectangle");

do structural reflection on c if needed.

c.compile(); writes bytecode on the original class file.

• Now the over written class file can be loaded in the JVM without user class loader

Use of Javassist

• Binary Code Adaption

• Remote Method Invocation

Comparison of OpenJava and Javassist

• Openjava needs source file of every processed class whereas Javassist needs just the class files of the classes

• Javassist is much faster as it can move compilation penalties to an earlier stage

Conclusion

• Javassist is portable

• Provides source level abstraction in a safe manner

• Does not need source code

• Can be extended to other object oriented languages with individually designed API for each language

The Jalapeno Dynamic Optimizing Compiler for java

Thomas J.Watson Research Center

IBM

Project overview

• Jalapeno is a JVM built by IBM Research (initiated in December 1997) It takes a compile-only approach to program execution• Three different compilers to provide translations: – A “baseline” compiler that makes it easier to mix

execution of un-optimized and optimized methods in the JVM

– A “quick” compiler for a low level of code optimization – An optimizing compiler for computationally intensive code

Motivation of the Project

• To deliver high performance and scalability ofJava applications on SMP server machines

• To support all Java features and semantics with respect to exceptions, garbage collection and threads

Jalapeno JVM• Jalapeno JVM includes the following subsystems: - Dynamic Class Loader - Dynamic Linker - Object Allocator - Garbage Collector - Thread Scheduler - Profiler - Three dynamic compilers

Jalapeno JVM

• All subsystems implemented in Java

• Self-bootstrapping

• Can dynamically self-optimize the JVM itself

Structure of Jalapeno Optimization system

• Unlike traditional JVMs, Jalapeno is adaptive

and dynamic

– Automatically select a set of methods to optimize

– Generate the best possible code for selected methods for a given compile-time budget

– Reduce synchronization and other thread primitive

Structure of Jalapeno adaptive Optimization system

• Jalapeno Adaptive Optimization System includes:

– On-Line Measurement (OLM) subsystem

– Controller subsystem

– Optimizing Compiler subsystem

Online Measurment

• OLM

– Collect application and hardware performance information

– Maintain Calling Context Graph (CCG) to keep track of context-sensitive information

– Continuously monitor the methods, including those previously “optimized”

Controller

• Controller

– Detect if certain performance threshold is reached

– Use information collected from OLM to build an optimization plan (e.g. which methods need to be compiled and the optimization levels)

Optimizing Compiler

• The Optimizing Compiler can be used either as a static or dynamic compiler.

• When used as a static compiler or a bytecode -to-bytecode optimizer, it generates file for later execution ,used to bootstrap Jalapeno JVM

Optimizing Compiler

• When used as a dynamic compiler, it

generates the best possible code given compile -time budget

• The Jalapeno Optimizing Compiler consists of an optimizer front-end and an optimizer backend

Intermediate Representation(IR)

• The Optimizing Compiler uses register-based intermediate representations

• IR consists of an operator and some number of operands

• Jalapeno uses 3 different types of IRs:

– HIR (High-Level IR)

– LIR (Low-Level IR)

– MIR (Machine-Specific IR)

IR

• Operators such as NULL_CHECK and BOUNDS_CHECK operators are used to facilitate optimization

• Control Flow Graph (CFG) and Basic Blocks (BB) are constructed as a by-product of BC2IR(Byte Code to Intermediate Representation)

Front end of Optimizing compiler

• The Front-End contains two parts:

– BC2IR algorithm to translate byte code to HIR and perform on the fly optimizations

– Additional optimization performed on the generated HIR

Back end of Optimizer Compiler• The Back-End of the compiler translates

– HIR to LIR

– LIR to MIR

– MIR to the final binary code• Different optimizations are performed during each

phase

HIR to LIR

• HIR is lowered to low-level IR (LIR)• LIR expands instructions into operations that are

specific to the Jalapeno JVM (such as object layouts or parameter-passing mechanism)

• The expanded LIR may expose more

opportunities for low-level optimizations

Final Assembly

• Emit the binary executable code into an

instruction array• Convert offsets in the IR to offsets in the

machine code• Store the instruction array (a Java array

reference) into a field of the object instance for that method

Inlining Method Calls

• During BC2IR phase:

– Static and final methods can be safely inlined.

– “Inlining plan” is based on static code size and depth heuristics

Implementation Status

• OLM is in prototype stage, and the controller is in design phase

• The Optimizing compiler can only be invoked as a static compiler or dynamically by the Jalapeno class loader to optimize all methods

Performance Benchmark Enviroments

• Four Java Environments:

– IBM JDK 1.1.6 w/o JIT

– IBM JDK 1.1.6 w IBM JIT v3.0

– Jalapeno Baseline – Use Jalapeno Baseline Compiler as a JIT for all classes dynamically loaded

– Jalapeno Optimizer – Use Jalapeno Optimizing as JIT for all classes dynamically loaded

Benchmark Programs

• Benchmark Programs:

– 9 “Micro-benchmark” Programs from Symantec

– 4 “Macro-benchmark” programs from SPECjvm98suite

Performance Results

• Micro-Benchmark:

– 3 of the 9 tests run faster with the Jalapeno Optimizing Compiler

– Remaining cases are within 1.6 times slower of the standard IBM JIT compiler

Performance Results

• Macro-Benchmark:

– 1.3 to 3.3 times slower than the “best” current commercial JVM"

– With further improvements, Jalapeno (a pure Java JVM) may achieve performance competitive to a state-of-the-art JVM implemented in C

Conclusion• First dynamic optimizing compiler for Java

that is being used in JVM with a compile –only approach to program execution

– Validated the “compile-only” approach to program execution

– Demonstrated that a JVM implemented in Java can deliver performance comparable to a standard JIT compiler


Recommended