42
Load Time Structural Reflection in Java Shigeru Chiba Institute of Information Science and Electronics University of Tsukuba

Load Time Structural Reflection in Java Shigeru Chiba Institute of Information Science and Electronics University of Tsukuba

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

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