State of java.lang.invoke Implementation in...
Transcript of State of java.lang.invoke Implementation in...
![Page 1: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/1.jpg)
1 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
State of java.lang.invoke Implementation in OpenJDK
Vladimir Ivanov HotSpot JVM Compile r Oracle Corp. JVM Language Summit 2015
![Page 2: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/2.jpg)
2 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
![Page 3: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/3.jpg)
3 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
2005
JSR 292 Support for Dynamically Typed Languages in the JVM
Method Handle API (Early Draft Review)
Java 7 Release
JSR 292 Expert Group
formed
Initial design sketch Expert Group reboot
API refinement (e.g., CONSTANT_MethodHandle)
API refinement (e.g., BootstrapMethods)
2006 2007 2008 2009 2010 2011
![Page 4: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/4.jpg)
4 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Method Handles in JDK 7 GA § Good
– Flexible and powerful. – MH graphs are aggressively inlined and optimized.
§ Not-so-good – “Performance cliff” when inlining does not occur – MH.invoke() is slow – NoClassDefFoundError in large applications
§ Ugly – No general fast path for compiled code – JVM is entangled in MH operations
![Page 5: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/5.jpg)
5 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Quest for a Better IR
§ Root problem: MH chains are wrong IR for the JVM
§ Lambda Forms for the rescue – Mostly-native moves into Java – Decouple representation decisions from the JVM – Meshes better with the JVM execution engine
§ translates to bytecode § Interprets and/or compiles
– Erases types, avoiding NCDFE issues
2012: Lambda Forms in 7u40
![Page 6: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/6.jpg)
6 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
MHs vs LFs
MH
LF
n:1 .form
public
internal “ [A lambda form is a] … symbolic, non-executable form of a method handle's invocation semantics.”
“A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values.”
javadoc
![Page 7: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/7.jpg)
7 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
The Grand Plan MH
CS MT
public n:1
.type
.target
MH = MethodHandle MT = MethodType CS = CallSite
n:1
JDK
![Page 8: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/8.jpg)
8 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
The Grand Plan MH
CS
LF
MN
MT
MTF
DMH
n:1 .form
n:1 .vmentry
public
internal
n:1
.type
.target
MH = MethodHandle MT = MethodType CS = CallSite LF = LambdaForm DMH = DirectMethodHandle BMH = BoundMethodHandle MN = MemberName MTF = MethodTypeForm
n:1
n:1
VM anon classes
BMH extends
JDK
![Page 9: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/9.jpg)
9 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
The Grand Plan MH
CS
LF
MN
JVM
MT
MTF
DMH
n:1 .form
n:1 .vmentry
n:1 .vmtarget
public
internal
n:1
.type
.target
MH = MethodHandle MT = MethodType CS = CallSite LF = LambdaForm DMH = DirectMethodHandle BMH = BoundMethodHandle MN = MemberName MTF = MethodTypeForm MHN = MethodHandleNative
n:1
n:1
JVM_Method
MH::linkTo* MH::invokeBasic
native stubs linkCallSite linkMethod
etc
Upcalls
MH::init/resolve setCallSiteTarget*
etc
VM calls
MHN
resolved_references[]
appendix
VM anon classes
BMH extends
methodHandles*.cpp
JDK
![Page 10: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/10.jpg)
10 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form
putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{ t3:J=DMH.fieldOffset (a0:L); t4:L=DMH.checkBase (a1:L); t5:L=DMH.checkCast (a0:L,a2:L); t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void}
Example: putfield / Lookup.findSetter
![Page 11: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/11.jpg)
11 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form
putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{ t3:J=DMH.fieldOffset (a0:L); t4:L=DMH.checkBase (a1:L); t5:L=DMH.checkCast (a0:L,a2:L); t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void} § Basic value type is one of { ref, int, long, float, double } + void
– represented as signature letters "LIJFD” + “V”
Example: putfield / Lookup.findSetter
![Page 12: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/12.jpg)
12 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form
putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{ t3:J=DMH.fieldOffset (a0:L); t4:L=DMH.checkBase (a1:L); t5:L=DMH.checkCast (a0:L,a2:L); t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void}
Example: putfield / Lookup.findSetter LF.names[7]
Name.function Name.arguments[]
Name.type Name.index
LF.debugName
LF.result = -1
LF.arity = 3
![Page 13: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/13.jpg)
13 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form
putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{ t3:J=DMH.fieldOffset (a0:L); t4:L=DMH.checkBase (a1:L); t5:L=DMH.checkCast (a0:L,a2:L); t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void}
Execution
![Page 14: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/14.jpg)
14 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form
Entry point: LambdaForm::vmentry Can point to:
– LambdaForm Interpreter – compiled bytecode
Execution
.form
MH
LF
MN
JVM_Method
.vmentry
.vmtarget
.from_interpreted .from_compiled
interpreter compiled code
MH
LF
class (VM anon)
?
![Page 15: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/15.jpg)
15 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Interpreter
![Page 16: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/16.jpg)
16 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Compiled Form static void putObjectFieldCast_000( Object, Object, Object ); 0: aload_0 1: invokestatic #16 // DMH.fieldOffset:... 4: lstore_3 5: aload_1 6: invokestatic #20 // DMH.checkBase:... 9: astore 5 11: aload_0 12: aload_2 13: invokestatic #24 // DMH.checkCast:... 16: astore 6 18: ldc #26 // <<sun.misc.Unsafe@3830f1c0>> 20: checkcast #28 // class sun/misc/Unsafe 23: aload 5 25: lload_3 26: aload 6 28: invokevirtual #32 // Unsafe.putObject:(Object;Object;)V 31: return
RuntimeVisibleAnnotations:
LambdaForm$Hidden, LambdaForm$Compiled, ForceInline
t3:J
t4:L
t5:L
t6:V
a0:L a1:L a2:L putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{
t3:J=DMH.fieldOffset (a0:L);
t4:L=DMH.checkBase (a1:L);
t5:L=DMH.checkCast (a0:L,a2:L);
t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void}
![Page 17: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/17.jpg)
17 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
VM Anonymous Classes Constant Pool Patching static void putObjectFieldCast_000(…); ... 18: ldc #26
// String “CONSTANT_PLACEHOLDER_0“ 20: checkcast #28
// class sun/misc/Unsafe 23: aload 5 25: lload_3 26: aload 6 28: invokevirtual #32 // Unsafe.putObject(...) 31: return
t6:V
putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{
t3:J=DMH.fieldOffset (a0:L);
t4:L=DMH.checkBase (a1:L);
t5:L=DMH.checkCast (a0:L,a2:L);
t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void}
ConstantPool
#26 = Utf8 “...”
...
resolved_references[] { ..., unsafeObj , ...}
Unsafe.defineAnonymousClass( LambdaForm.class, byte[] {…}, Object[] { …, unsafeObj, …})
#26
![Page 18: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/18.jpg)
18 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
MHs vs LFs
§ Shared Lambda Form – many method handles share a
single LF instance
§ Customized Lambda Form – LF instance is customized for
some particular method handle
Sharing vs Customization
LF
LF
MH
MH
![Page 19: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/19.jpg)
19 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
MHs vs LFs
putObjectFieldCast_000=Lambda(a0:L,a1:L,a2:L)=>{
t3:J=DMH.fieldOffset (a0:L);
t4:L=DMH.checkBase (a1:L);
t5:L=DMH.checkCast (a0:L,a2:L);
t6:V=Unsafe.putObject((Unsafe@...),t4:L,t3:J,t5:L);void}
Example: putfield / Lookup.findSetter
LF
MH
.form
LOOKUP.findSetter( MyClass1.class, “f1", Field1.class);
MT Field2.class
offset2
(MyClass2,Field2)void (MyClass1,Field1)void
Field1.class offset1
LOOKUP.findSetter( MyClass2.class, “f2", Field2.class);
… constructs …
(L,L,L)void .form LF
MH
![Page 20: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/20.jpg)
20 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
MHs vs LFs
putIntField_000=Lambda(a0:L,a1:L,a2:I)=>{
t3:J=DMH.fieldOffset (a0:L);
t4:L=DMH.checkBase (a1:L);
t5:V=Unsafe.putInt((Unsafe@...),t4:L,t3:J,a2:I);void}
Example: putfield / Lookup.findSetter
LF
MH
.form
LOOKUP.findSetter( MyClass1.class, “i1", int.class);
MT long.class
offset2
(MyClass2,long)void (MyClass1,int)void
int.class offset1
LOOKUP.findSetter( MyClass2.class, “l2", long.class);
… constructs …
(L,L,I)void .form LF
MH
putLongField_000=Lambda(a0:L,a1:L,a2:J)=>{
t3:J=DMH.fieldOffset (a0:L);
t4:L=DMH.checkBase (a1:L);
t5:V=Unsafe.putLong((Unsafe@...),t4:L,t3:J,a2:J);void}
(L,L,J)void
![Page 21: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/21.jpg)
21 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
7 GA 8 GA 7u40 8u20 8u40
Lambda Forms j.l.i enhancements Type speculation in C2 Math.exact*() intrinsics
Nashorn Project Lambda
JSR 292 Released Lambda Form Sharing
![Page 22: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/22.jpg)
22 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
![Page 23: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/23.jpg)
23 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Caching 8u40: JEP 210
LF
MH
LF
MH ~106
~106 ~103
~104 ~103
classes classes
![Page 24: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/24.jpg)
24 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Sharing vs Customization Example: MHs.guardWithTest()
T guard(A... a, B... b) { if (test(a...)) return target(a..., b...); else return fallback(a..., b...); }
guard=Lambda(a0:L, a…, b…) => { t1:I =<<test>>(a…); t2:L=MHI.selectAlternative( t1:I, <<target>>, <<fallback>>); t3:?=MH.invokeBasic(t2:L, a…, b…);t3}
![Page 25: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/25.jpg)
25 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Sharing vs Customization Example: Customized version
guard_000=Lambda(a0:L)=>{ t1:I =(MH()boolean@...); t2:L=MHI.selectAlternative( t1:I,(MH()void@...),(MH()void@...)); t3:V=MH.invokeBasic(t2:L);void}
static void guard_000(Object); ldc ... // <<MethodHandle()boolean>> checkcast ... // class MethodHandle invokevirtual ... // MethodHandle.invokeBasic:()I … if_icmpne … ldc ... // <<MethodHandle()void>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MethodHandle.invokeBasic:()V goto … ldc ... // <<MethodHandle()void>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MethodHandle.invokeBasic:()V return
t1:I
test: MethodHandle target: MethodHandle fallback: MethodHandle
t2:L +
t3:V
![Page 26: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/26.jpg)
26 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Sharing vs Customization Example: Shareable version
guard_000=Lambda(a0:L)=>{ t3:L=BMH$Species_L3.argL0(a0:L); // test t4:L=BMH$Species_L3.argL1(a0:L); // target t5:L=BMH$Species_L3.argL2(a0:L); // fallback t6:I =MethodHandle.invokeBasic(t3:L); t7:L=MethodHandleImpl.selectAlternative(t6:I,t4:L,t5:L); t8:V=MethodHandle.invokeBasic(t7:L);void}
![Page 27: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/27.jpg)
27 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Sharing
§ Smaller dynamic footprint – # of loaded classes, Metaspace size
§ Faster startup/warmup – less LFs to instantiate, less classes to load, less code to compile
§ Enables new optimizations – Lambda Form precompilation – Improves worst case stack consumption
Pros
![Page 28: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/28.jpg)
28 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Sharing Dynamic Footprint
1
2
4
8
16
metaspace
classes
Measurements by Sergey Kuksenko 8u40: b05 vs b21, Nashorn
ratio
Octane
higher/better
![Page 29: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/29.jpg)
29 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Sharing Startup / Warmup
-80
-30
20
70
120
8u40: b05 vs b21, Nashorn
354%
%
1st iteration duration higher/better
![Page 30: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/30.jpg)
30 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Precompilation
§ Before: – first 30 invocations go through LF interpreter – then compiled to bytecode
§ After: – Lambda Form is precompiled during creation – completely bypasses LF interpreter
![Page 31: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/31.jpg)
31 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Stack Consumption
jdk.nashorn.internal.scripts.Script$Recompilation$2$test.f1(test.js:1) j.l.i.LambdaForm$DMH/804581391.invokeStatic_LL_L
j.l.i.LambdaForm$DMH/1854778591.invokeSpecial_L3_L
j.l.i.LambdaForm$NamedFunction.invoke_LLL_L
j.l.i.LambdaForm$DMH/804581391.invokeStatic_LL_L
j.l.i.LambdaForm$NamedFunction.invokeWithArguments
j.l.i.LambdaForm.interpretName
j.l.i.LambdaForm.interpretWithArguments
j.l.i.LambdaForm.interpret_L
j.l.i.LambdaForm$DMH/1854778591.invokeSpecial_L3_L
j.l.i.LambdaForm$NamedFunction.invoke_LLL_L
j.l.i.LambdaForm$DMH/804581391.invokeStatic_LL_L
j.l.i.LambdaForm$NamedFunction.invokeWithArguments
j.l.i.LambdaForm.interpretName
j.l.i.LambdaForm.interpretWithArguments
j.l.i.LambdaForm.interpret_L
j.l.i.LambdaForm$MH/2142080121.linkToCallSite
jdk.nashorn.internal.scripts.Script$Recompilation$1$test.:program(test.js:2)
Lambda Form Interpreter
reinvoke
exactInvoker
test.js: 1: function f1() {} 2: f1()
![Page 32: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/32.jpg)
32 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Stack Consumption
jdk.nashorn.internal.scripts.Script$Recompilation$2$test.f1(test.js:1) j.l.i.LambdaForm$DMH/804581391.invokeStatic_LL_L j.l.i.LambdaForm$BMH/921760190.reinvoke j.l.i.LambdaForm$MH/1690254271.exactInvoker j.l.i.LambdaForm$MH/206835546.linkToCallSite
jdk.nashorn.internal.scripts.Script$Recompilation$1$test.:program(test.js:9)
Compiled Form
![Page 33: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/33.jpg)
33 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Sharing Peak Performance
-20
-10
0
10
20
30
40
Measurements by Sergey Kuksenko 8u40: b05 vs b21, Nashorn
125%
%
higher/better
![Page 34: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/34.jpg)
34 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lambda Form Sharing
§ Profile pollution – peak performance suffers
§ Non-constant MH calls became slower – JIT can’t inline through them – less optimized machine code
Problems in 8u40
![Page 35: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/35.jpg)
35 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution
Customization vs Sharing
![Page 36: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/36.jpg)
36 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Customized version
static void guard_000(Object); ldc ... // <<test>> checkcast ... // class MethodHandle invokevirtual ... // MethodHandle.invokeBasic:()I … if_icmpne … ldc ... // <<target>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MH.invokeBasic:()V goto … ldc ... // <<fallback>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MethodHandle.invokeBasic:()V return
t1:I
t2:L +
t3:V guard_000=Lambda(a0:L)=>{ t1:I =<<test>>(); t2:L=MethodHandleImpl.selectAlternative( t1:I,<<target>>,<<fallback>>); t3:V=MethodHandle.invokeBasic(t2:L);void}
![Page 37: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/37.jpg)
37 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Customized version
static void guard_000(Object); ldc ... // <<alwaysTrue>> checkcast ... // class MethodHandle invokevirtual ... // MH.invokeBasic:()I … if_icmpne … ldc ... // <<target>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MH.invokeBasic:()V goto … ldc ... // <<fallback>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MH.invokeBasic:()V return
t1:I
t2:L +
t3:V
0%
guard_000=Lambda(a0:L)=>{ t1:I =<<alwaysTrue>>(); t2:L=MethodHandleImpl.selectAlternative( t1:I,<<target>>,<<fallback>>); t3:V=MethodHandle.invokeBasic(t2:L);void}
![Page 38: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/38.jpg)
38 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Customized version
static void guard_001(Object); ldc ... // <<alwaysFalse>> checkcast ... // class MethodHandle invokevirtual ... // MH.invokeBasic:()I … if_icmpne … ldc ... // <<target>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MH.invokeBasic:()V goto … ldc ... // <<fallback>> checkcast ... // class MethodHandle astore_2 aload_2 invokevirtual ... // MH.invokeBasic:()V return
t1:I
t2:L +
t3:V
100%
guard_001=Lambda(a0:L)=>{ t1:I =<<alwaysFalse>>; t2:L=MethodHandleImpl.selectAlternative( t1:I,<<target>>,<<fallback>>); t3:V=MethodHandle.invokeBasic(t2:L);void}
![Page 39: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/39.jpg)
39 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Shared version
static void guard_000(Object); aload_0 checkcast … // BMH$Species_L3 getfield ... // BMH$Species_L3.argL0:Object invokevirtual ... // MH.invokeBasic:()I … if_icmpne … aload_2 checkcast ... // class MethodHandle astore_5 aload_5 invokevirtual ... // MH.invokeBasic:()V goto … aload_3 checkcast ... // class MethodHandle astore_5 aload_5 invokevirtual ... // MH.invokeBasic:()V return
???%
![Page 40: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/40.jpg)
40 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution How to fix
static void guard_000(Object); aload_0 checkcast … // BMH$Species_L3 getfield ... // BMH$Species_L3.argL0:Object invokevirtual ... // MH.invokeBasic:()I … if_icmpne … aload_2 checkcast ... // class MethodHandle astore_5 aload_5 invokevirtual ... // MH.invokeBasic:()V goto … aload_3 checkcast ... // class MethodHandle astore_5 aload_5 invokevirtual ... // MH.invokeBasic:()V return
?%
§ Idea: customized profiling – collect per-MethodHandle profile
during warm-up – inject profile into the JVM when
warm-up is over
![Page 41: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/41.jpg)
41 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Custom Branch Profiling
guard_000=Lambda(a0:L)=>{ t1:L=BMH$Species_L4.argL0(a0:L); // test t2:L=BMH$Species_L4.argL1(a0:L); // target t3:L=BMH$Species_L4.argL2(a0:L); // fallback t4:L=BMH$Species_L4.argL3(a0:L); // counts (int[2]) t5:I =MethodHandle.invokeBasic(t1:L); t6:I =MethodHandleImpl.profileBoolean(t5:I,t4:L); t7:L=MethodHandleImpl.selectAlternative(t6:I,t2:L,t3:L); t8:V=MethodHandle.invokeBasic(t7:L);void}
![Page 42: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/42.jpg)
42 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Custom Branch Profiling Logic
§ profiling / warm-up – interpreter / C1 – C2 when counts array is unknown
§ per-LambdaForm compiled method
§ optimized – C2 intrinsic – injects per-MH counts into IR
![Page 43: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/43.jpg)
43 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution Custom Branch Profiling Logic
§ profiling / warm-up – interpreter / C1 – C2 when counts array is unknown
§ per-LambdaForm compiled method
§ optimized – C2 intrinsic – injects per-MH counts into IR
![Page 44: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/44.jpg)
44 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution
§ Type profile – not a problem – Type speculation (by Roland Westrelin in 8u20)
§ -XX:+UseTypeProfile -XX:TypeProfileLevel=[012]{3}
§ Deoptimization counts – no generic solution yet – fixed some manifestations of the problem
§ JDK-8074551: GWT can be marked non-compilable due to deopt count pollution
Other cases
![Page 45: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/45.jpg)
45 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Non-Constant Method Handle
Invocation
MH.invokeExact() et al
![Page 46: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/46.jpg)
46 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Non-Constant Method Handle Invocation Non-constant method handle
@ 105 jsr292.GWT::run1 (7 bytes) inline (hot) @ 3 java.lang.invoke.LambdaForm$MH/789451787::invokeExact_MT (13 bytes) inline (hot) @ 2 java.lang.invoke.Invokers::checkExactType (30 bytes) inline (hot) @ 11 java.lang.invoke.MethodHandle::type (5 bytes) accessor @ 9 java.lang.invoke.MethodHandle::invokeBasic()V (0 bytes) receiver not constant
![Page 47: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/47.jpg)
47 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Non-Constant Method Handle Invocation Customized version java.lang.invoke.LambdaForm$MH/1510467688::guard (56 bytes)
@ 5 java.lang.invoke.LambdaForm$DMH/1581781576::invokeStatic__I (13 bytes) inline (hot) @ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) inline (hot) @ 9 jsr292.GWT::test1 (12 bytes) inline (hot) @ 31 java.lang.invoke.LambdaForm$DMH/1581781576::invokeStatic__V (13 bytes) inline (hot) @ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) inline (hot) @ 9 jsr292.GWT::f1 (2 bytes) inline (hot) @ 52 java.lang.invoke.LambdaForm$DMH/1581781576::invokeStatic__V (13 bytes) inline (hot) @ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes) inline (hot) @ 9 jsr292.GWT::f2 (2 bytes) inline (hot)
![Page 48: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/48.jpg)
48 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Non-Constant Method Handle Invocation Shared version java.lang.invoke.LambdaForm$MH/1252585652::guard (68 bytes)
@ 24 java.lang.invoke.MethodHandle::invokeBasic()I (0 bytes) receiver not constant @ 47 java.lang.invoke.MethodHandle::invokeBasic()V (0 bytes) receiver not constant @ 64 java.lang.invoke.MethodHandle::invokeBasic()V (0 bytes) receiver not constant
![Page 49: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/49.jpg)
49 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
§ Customized Lambda Form – single compiled method per
MH chain / root LF
§ Shared Lambda Form – compiled method per MH/LF
Non-Constant Method Handle Invocation
nmethod
![Page 50: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/50.jpg)
50 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Non-Constant Method Handle Invocation
nmethod Solution: Optional Customization § Original (shared) guard_000=Lambda(a0:L)=>{ t1:L=BMH$Species_L4.argL0(a0:L); … § Customized (a0 is overridden by t1:L) guard_000=Lambda(a0:L)=>{ t1:L=<<MethodHandle …>> t2:L=BMH$Species_L4.argL0(t1:L); …
![Page 51: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/51.jpg)
51 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
7 GA 8 GA 9+
Timeline
7u40 8u20 8u40
λ-form sharing
Performance fixes
(e.g. per-MH profiling, LF customization)
λ-forms catchException λ-form sharing
type speculation Math.exact*() intrinsics
Now
8u60
Nashorn Project Lambda
Aug, 2015
![Page 52: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/52.jpg)
52 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Future work
• Ultimate Sharing • MH.asType() Optimization • Reduce Stack Consumption • Lightweight Code Loading • Profile Pollution
![Page 53: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/53.jpg)
53 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Ultimate Sharing
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ I , J , L , … , F ]
...
Currently: Lambda Form instance per erased signature
Goal: Single Lambda Form instance per unit of behavior
call site
LF
LF
target
![Page 54: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/54.jpg)
54 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Ultimate Sharing
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ L , L , L , … , L ]
[ L , L , L , … , L ]
...
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ I , J , L , … , F ]
...
call site
LF
LF
target
No conversions Boxing
![Page 55: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/55.jpg)
55 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Ultimate Sharing
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ L , L , L , … , L ]
[ L , L , L , … , L ]
...
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ I , J , L , … , F ]
...
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ L ]
[ L ]
call site
LF
LF
target
No conversions Boxing Boxing + VarArgs
![Page 56: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/56.jpg)
56 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Ultimate Sharing
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ ]
[ ]
§ JVM support is needed – reliable box/unbox elimination – array explosion
[ I , J , L , … , F ]
[ I , J , L , … , F ]
[ L ]
[ L ]
![Page 57: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/57.jpg)
57 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
MethodHandle.asType()
§ Improve caching/sharing of MH.asType() transformations – type adaptations are expensive to construct
§ Single-element per-MH cache – subject to profile pollution
§ MH.invoke() on shared MH doesn’t work well – (w.r.t. peak performance)
Better Caching / Sharing
![Page 58: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/58.jpg)
58 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Reduce stack consumption
jdk.nashorn.internal.scripts.Script$Recompilation$2$test.f1(test.js:1) j.l.i.LambdaForm$DMH/804581391.invokeStatic_LL_L j.l.i.LambdaForm$BMH/921760190.reinvoke j.l.i.LambdaForm$MH/1690254271.exactInvoker j.l.i.LambdaForm$MH/206835546.linkToCallSite
jdk.nashorn.internal.scripts.Script$Recompilation$1$test.:program(test.js:9)
Precompiled Lambda Forms
![Page 59: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/59.jpg)
59 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Reduce stack consumption
jdk.nashorn.internal.scripts.Script$Recompilation$2$test.f1(test.js:1) j.l.i.LambdaForm$DMH/804581391.invokeStatic_LL_L j.l.i.LambdaForm$BMH/921760190.reinvoke j.l.i.LF$MH/….customized j.l.i.LambdaForm$MH/1690254271.exactInvoker j.l.i.LambdaForm$MH/206835546.linkToCallSite
jdk.nashorn.internal.scripts.Script$Recompilation$1$test.:program(test.js:9)
(1) Lambda Form Inlining
![Page 60: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/60.jpg)
60 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Reduce stack consumption
jdk.nashorn.internal.scripts.Script$Recompilation$2$test.f1(test.js:1) j.l.i.LambdaForm$MH/483294845.customized j.l.i.LambdaForm$MH/206835546.linkToCallSite
jdk.nashorn.internal.scripts.Script$Recompilation$1$test.:program(test.js:9)
(1) Lambda Form Inlining
![Page 61: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/61.jpg)
61 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Reduce stack consumption
§ Pros – easy to implement – doesn’t require any JVM extensions
§ Cons – defeats Lambda Form sharing
§ too many indy call sites to specialize for § VM anonymous classes are too heavyweight
(1) Lambda Form Inlining
![Page 62: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/62.jpg)
62 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Reduce stack consumption
jdk.nashorn.internal.scripts.Script$Recompilation$2$test.f1(test.js:1) (*)
jdk.nashorn.internal.scripts.Script$Recompilation$1$test.:program(test.js:9) (*) during invocation: linkToCallSite =tail-call=> reinvoke =tail-call=> exactInvoker =tail-call=> invokeStatic_LL_L =tail-call=> …$test.f1
(2) Tail Calls
![Page 63: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/63.jpg)
63 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lightweight Code Loading VM Anonymous Classes
Class<?> Unsafe.defineAnonymousClass( Class<?> hostClass, byte[] code, Object[] cpPatches)
![Page 64: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/64.jpg)
64 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lightweight Code Loading VM Anonymous Classes
Class<?> Unsafe.defineAnonymousClass( Class<?> hostClass, byte[] code, Object[] cpPatches)
![Page 65: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/65.jpg)
65 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Lightweight Code Loading
MethodHandle Lookup.loadCode( /*Class<?> hostClass,*/ byte[] code, Object[] cpPatches)
![Page 66: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/66.jpg)
66 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Profile Pollution
LF
MH
class
![Page 67: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/67.jpg)
67 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Future Extensions
• Variable Handles • Small API Enhancements • Native Calls
![Page 68: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/68.jpg)
68 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
JEP 193: Variable Handles
§ Safe, performant, enhanced atomics – access to fields and array elements
§ VarHandles are like method handles for data – Abstracts over location – static fields, instance fields, arrays, off heap – Supports explicit fences and atomic operation
§ Safer than Unsafe, as fast as MethodHandles
JEP-193 “Variable Handles” by Doug Lea, Paul Sandoz http://openjdk.java.net/jeps/193
![Page 69: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/69.jpg)
69 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
API Enhancements
§ Candidates – MHs.tryFinally() – MHs.*Loop() – Lookup.lookupClass()/findSuperConstructor() – Additional combinators for argument handling
§ e.g. MHs.spreadArguments(MH target, int pos, int count)
[email protected] discussion http://mail.openjdk.java.net/pipermail/mlvm-dev/2015-February/006288.html
![Page 70: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/70.jpg)
70 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Native Calls Project Panama: FFI
Java Native
Construction Lookup.findVirtual() et al Lookup.findNative()
Reference (typed) DirectMethodHandle NativeMethodHandle
Reference (direct) MemberName NativeEntryPoint
Linker MH.linkToVirtual() et al MH.linkToNative()
Invocation indy, MH.invoke(), MH.invokeExact()
“Making native calls from the JVM” by John Rose http://cr.openjdk.java.net/~jrose/panama/native-call-primitive.html
![Page 71: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/71.jpg)
71 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Thank you!
@iwan0www
![Page 72: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/72.jpg)
72 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Materials
§ Implementation Notes:– http://cr.openjdk.java.net/~vlivanov/talks/2015-Indy_Deep_Dive.pdf
§ https://wiki.openjdk.java.net/display/HotSpot/Method+handles+and+invokedynamic § https://wiki.openjdk.java.net/display/HotSpot/Bound+method+handles § https://wiki.openjdk.java.net/display/HotSpot/Direct+method+handles § https://wiki.openjdk.java.net/display/HotSpot/Method+handle+invocation § "Deconstructing MethodHandles” by Paul Sandoz
– https://wiki.openjdk.java.net/display/HotSpot/Deconstructing+MethodHandles § "Lambda Forms” by John Rose, JVMLS'12
– http://cr.openjdk.java.net/~jrose/pres/201207-LF-Tutorial.pdf
§ “J9's MethodHandle Compilation Pipeline” by Dan Heidinga, Jfocus VM Summit’15 – http://www.jfokus.se/jfokus15/preso/J9%20MethodHandle%20Compilation%20Pipeline.pdf
![Page 73: State of java.lang.invoke Implementation in OpenJDKcr.openjdk.java.net/~vlivanov/talks/2015-JVMLS_State_of_JLI.pdf · Basic value type is one of { ref, int, long, float, double }](https://reader034.fdocuments.in/reader034/viewer/2022052011/60263093033bb96fbd23fe65/html5/thumbnails/73.jpg)
73 Copyright © 2015, Oracle and/or its affiliates. All rights reserved
Graphic Section Divider