Aggressive unboxing of values: status update

Albert Noll albert.noll at oracle.com
Tue Nov 4 10:11:36 UTC 2014


Hi all,

I've been working on aggressive unboxing of values over the past couple 
of weeks. The project is in a very early state. The current prototype is 
designed around two principles: (1) implement unboxing as described 
below, (2) keep the required changes reasonably small. As a result, 
there is lots of potential for optimization. These optimizations can be 
added in later stages of the project. Aggressive unboxing aims at 
providing an efficient way to:

(1) pass values as parameters to functions
(2) return values from functions
(3) load and store flattened data in the heap
(4) provide insight into the implementation of value types

Let's consider this simple example:

value Complex {
   int x, int y;
   private Complex(int x, int y) {
     this.x = x;
     this.y = y;
   }
   public static Complex make(int x, int y) {
     return new Complex(int x, int y);
   }
}

class Test {
   void non_inlined_callee(Complex c) {
     int sum = c.x + c.y;
     System.out.println(sum);
   }
   void caller() {
     Complex c = Complex.make(1, 2);
     non_inlined_callee(c);
   }
}

Let's assume that Complex.make() and the constructor in Complex.make() 
is inlined into caller(). The compiler decides to not inline 
non_inlined_callee(). The current prototype recognizes that 'Complex' is 
a value and uses the unboxed components (x and y) to pass them to 
non_inlined_callee. I.e., the JIT compiler transforms the original call 
'non_inlined_callee(Complex c)' to 'non_inlined_callee(Complex c, int x, 
int y)'. Why to we keep the parameter 'Complex c'? The reason is that we 
want to keep - for now - the interpreter unmodified. I.e., by keeping 
'Complex c' in the signature, non_inlined_callee() can call native 
methods, the interpreter, or a C1 compiled method.

This is not optimal, but keeps things simple for now. In a later stage 
of the project, we plan to implement a 'boxing operation'. Boxing an 
unboxed value would be done only on demand. One thing that we need to 
think about is how we deal OOMEs when implementing 'lazy boxing'.
If non_inlined_callee() is compiled with C2, the compiled code expects 
the unboxed parameters and uses the unboxed arguments instead of the 
original reference to 'Complex c'. One benefit of using the unboxed 
parameters instead of the original object is that the JIT needs to be 
less conservative and therefore the compiled code quality is potentially 
better.
Providing this functionality (to prototype is not yet stable) requires 
changing ~2k lines in Hotspot. Many of the affected changes are in 
'critical' places. That's why I want to make sure that the prototype is 
reasonably stable before pushing. Current support for unboxing is 
implemented only in C2. The interpreter and C1 can remain unchanged for 
now. I have a bachelor student who is looking into a corresponding C1 
implementation.

Development Plan:
- Finish passing values as unboxed parameters for static methods
- Return values in registers for static methods
- Implement boxing operation
- Pass 'this' unboxed
- Make function calls without passing the allocated value object

Best,
Albert


More information about the valhalla-dev mailing list