Lazy Method Handles is a project to defer code generation for method handle 
behavior, and minimize requirements for support from hand-written assembly code.

The idea is to make all method handle behavior visible to the JVM compiler, so 
that it can be optimized properly.  Assembly code cannot be optimized.

In JDK 7 FCS a method handle is represented as a chain of argument 
transformation blocks, ending in a pointer to a methodOop.  The argument 
transformations are assembly coded and work in the interpreter stack.  The 
reason this is not outrageously slow is that we vigorously inline method handle 
calls whenever we can.  But there is a performance cliff you can drop off of, 
when you are working with non-constant MHs.  (BTW, invokedynamic almost always 
inlines its target.)  Project Lambda needs us not to drop off of this cliff.

To fix this, we are now representing the argument transformations using a 
simple AST-like IR, called a LambdaForm.  This form can be easily rendered down 
to bytecodes.  (Eventually it maybe directly rendered to native code.)  The 
form is *also* interpretable by a Java-coded AST walker.  This allows the 
system to be lazy, and to work hardest on optimizing those method handles that 
are actually called frequently.  The laziness also helps simplify 
bootstrapping.  The remaining assembly code is much smaller, and can be 
mirrored in the JIT IR and optimized.

Here's an update on where we are.  Christian Thalinger, Michel Haupt, and I are 
currently working on the following tasks:

A. clean out the compiled method calling path, for non-constant method handles
B. flatten the BMH layout (no boxing, linked lists, or arrays)
C. make the handling of MethodType checking visible to the compiler (removing 
more assembly code)
D. tuning reuse and compilation of LambdaForm instances
E. profiling MH.LambdaForm values at MH call sites
F. tuning optimization of call sites involving LFs

For A. the remaining snag is getting the argument register assignments correct 
for the call to the target method.  There is also an issue with representing 
non-nominal calls in the backend.

For B. we are currently working on bootstrap issues.  The idea here is that, 
while we can do escape analysis, etc., a cleaner data structure will make the 
compiler succeed more often.

For C. we have a refactoring in process for moving the MT value out of the 
methodOop.

Chris, Michael, and I are working on A, B, C, respectively.  We think a first 
cut of lazy MHs needs the first three items in order to be reasonably faster 
than the all-assembly implementation of JDK 7.

In order to address the infamous NoClassDefFound error, we are minimizing 
nominal information in MH adapter code (LambdaForms and their bytecode).  Only 
names on the BCP will be in adapter code.   Part C. is an important part of 
this, since it allows the system to internally "flatten" calls like 
MH.invokeExact((MyFunnyType)x) to MH.invokeExact((Object)x).  The new internal 
MH methods (invokeBasic, invokeStatic, etc.) all use "denominalized" types, 
which is to say that all reference types are represented as java.lang.Object.

Best wishes,
— John
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to