Transcript slides

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 is
not 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 -tobytecode 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