Hotspot loves PHP.reboot
John Rose
john.r.rose at oracle.com
Wed Sep 7 16:12:35 PDT 2011
On Sep 7, 2011, at 3:28 PM, Rémi Forax wrote:
> On 09/07/2011 10:38 PM, John Rose wrote:
>>
>> Object l0, l1, l2, ...;
>> l0 = l1 = l2 = ... null; // these are required only for definite assignment in the catch body
>> try {
>> ...do fast path...
>> if (...constraint violated...) throw new DeoptExc(...);
>> return ...fast result...
>> } catch (DeoptExc ex) {
>> Object[] display = { l0, l1, l2, ... };
>> return backupInterpreter(ex, display); // N.B. could throw DeoptExc to caller also
>> }
>>
>> This problem is that the eager initializations of the various locals slow down the fast path. (Did I get it right Remi?) The register allocator should push them down into the catch body, and maybe even into the static debug info of the JVM.
>
> Locals is not the only problem, you have to track stack values too.
To clarify, I meant only JVM locals, which serve as virtual registers for the application language locals, stacks, whatever. JVM stack elements are guaranteed to be thrown away when a JVM exception is thrown, so they function like virtual registers that are blown by deopt. events.
> It's the combination of locals initialization, local variable creation
> for storing stack values
Yes, if there are logically stacked values that need tracking into slow paths, they need to be spilled to JVM locals. The cost of this will be reduced by good register allocations in the JIT. Ensuring this is part of the tuning job.
> and supplementary exception handlers
> (that's the main problem, or you have multiple handlers,
> or you have one handler and a constant)
> that slow down the fast path.
I think a single handler is going to be simpler all the way around. Thus, the deopt. source location and value display map have to be stored somewhere so they can be made a parameter to the handler. I think the exception object is the most likely place to store it; TLS is also a candidate.
To extend on your cute idea below, have the source location and value display map be static parameters to the invokedynamic instruction which initiates transfer to the slow path. That way everything is in the class file, but lazily unpacked only if needed. There's little or no need to use executable bytecode instructions (other than an indy at the throw point and an indy in the local handler) to manage the deopt. transition. The actual bytecodes can be devoted to executing the fast path code, and testing for type-state faults.
BTW, although one might think that the repertoire for static BSM arguments is limited (string, class, int, long, MH, MT), note that the MH gives a hook to open-ended constant formation. Just treat the MH as a thunk to be executed to materialize a desired constant.
> Also, in the catch block you can use invokedynamic to avoid
> the object array creation at call site.
Yes, cute idea. Simplifying code on the slow path should make for faster loading and startup.
Or (putting on my Pack200 hat), invokedynamic is the ultimate code-stream compressor.
-- John
More information about the mlvm-dev
mailing list