RFR(L): 8143211: provide bytecode intrinsics for loop and try/finally executors
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Tue Jun 21 17:05:50 UTC 2016
Nice work, Michael!
Some comments follow:
===
src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java:
+ private final List<Class<?>> loopClauseTypes;
+ /** This list contains the actual local state types added by loop
clauses, without {@code void} entries. */
+ private final List<Class<?>> loopLocalStateTypes;
+ /** The first slot after the arguments, to contain the first loop
state element. */
+ private final int firstLoopStateSlot;
You assume there's at most a single loop intrinsic in a compiled LF
instance.
It's the case now, but it's not necessarily the case in the future.
There's no such limitation for other intrinsics and I'd prefer to keep
it that way.
Why not iterate over the LF to compute localsMap & localClasses? You can
restore the information in emitLoop() from the intrinsic (localStateDesc).
===
src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java:
+ * The LambdaForm shape for the loop combinator is as follows
(assuming one reference parameter passed in
...
+ * tryFinally=Lambda(a0:L,a1:L)=>{
...
+ * t9:L=MethodHandleImpl.loop(t2:L,t3:L,t4:L,t5:L,t6:L); //
call the loop executor
Wrong LambdaForm name in the example (tryFinally vs loop).
===
1058 private static BoundMethodHandle
makeBoundHandle(BoundMethodHandle.SpeciesData data, Object... args) {
1059 try {
1060 return (BoundMethodHandle)
data.constructor().invokeWithArguments(args);
1061 } catch (Throwable ex) {
1062 throw uncaughtException(ex);
1063 }
1064 }
It can be used in makeGuardWithTest as well.
I like the helper method, but it can cause bootstrapping issues (due to
MH.invokeWithArguments which depends on j.l.i machinery) if used
unwisely. I think that's the main reason why invokeBasic was used in the
first place.
===
+ static final class IntrinsicMethodHandle extends
DelegatingMethodHandle {
...
+ private final String localStateDesc;
Maybe subclass IntrinsicMH instead?
LoopIntrinsic extends IntrinsicMethodHandle {
private final String localStateDesc;
LoopIntrinsic(MethodHandle target, String localStateDesc) {
super(target,Intrinsic.LOOP);
this.localStateDesc = localStateDesc;
}
...
String getLocalStateDesc() {
return localStateDesc;
}
}
static MethodHandle makeLoopIntrinsic(MethodHandle target, String
localStateDesc) {
return new LoopIntrinsic(target, localStateDesc);
}
Also, you can consider getting rid of IMH and moving intrinsic
information to LambdaForm.NamedFunction (akin to
LambdaForm.Name.constraint). I was responsible for adding IMH, but
LambdaForm.NameFunction looks like a better place now.
===
src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java:
+ Map<String, SoftReference<LambdaForm>> loopLambdaForms;
What about purging of stale entries from the cache?
Have you considered reusing LambdaFormEditor? E.g., put a root LF (w/
empty local state?) in MTF slot and fork new LFs (w/ non-empty local
state) from it?
Best regards,
Vladimir Ivanov
On 6/16/16 4:17 PM, Michael Haupt wrote:
> Dear all,
>
> please review this change.
> RFE: https://bugs.openjdk.java.net/browse/JDK-8143211
> Webrev: http://cr.openjdk.java.net/~mhaupt/8143211/webrev.00/
>
> The change puts the tryFinally and loop method handle combinator implementations, which were introduced as part of the JEP 274 effort, on a LambdaForm basis, which executes in bytecode generating (default) and LambdaForm interpretation (-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=-1) modes. It also changes the output formatting of LambdaForms, introducing a (hopefully) more readable format.
>
> Thanks,
>
> Michael
>
More information about the core-libs-dev
mailing list