-
Bug
-
Resolution: Fixed
-
P4
-
repo-valhalla
Valhalla causes performance slowdown for reflective invocations (due to DelegatingMethodAccessorImpl.invoke and GeneratedMethodAccessor1.invoke were not inlined)
Benchmark location: http://cr.openjdk.java.net/~skuksenko/valhalla/legacy/benchmarks/
Benchmark: reflect.MethodInvoke
Performance difference vs pre-valhalla world is ~20% for invocation of single argument method and 2x times on 6-argument method (doesn't matter if arguments are primitive or reference).
According to profilers data the reason is the following:
- Call chain for reflective invocation looks as:
org.openjdk.reflect.MethodInvoke.invokeWithSixObjectParams()
java.lang.reflect.Method.invoke(...)
jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(...)
jdk.internal.reflect.GeneratedMethodAccessor1.invoke(...)
org.openjdk.reflect.MethodInvoke.staticMethodWithSixObjectParams(...)
- In pre-valhalla world all 3 intermediate methods were inlined and final invocation chain in code is:
reflect.MethodInvoke.invokeWithSixObjectParams()
reflect.MethodInvoke.staticMethodWithSixObjectParams(...)
- In valhalla only Method.invokewas inlined. Final invocation chain is:
org.openjdk.reflect.MethodInvoke.invokeWithSixObjectParams()
jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(...)
jdk.internal.reflect.GeneratedMethodAccessor1.invoke(...)
org.openjdk.reflect.MethodInvoke.staticMethodWithSixObjectParams(...)
Benchmark location: http://cr.openjdk.java.net/~skuksenko/valhalla/legacy/benchmarks/
Benchmark: reflect.MethodInvoke
Performance difference vs pre-valhalla world is ~20% for invocation of single argument method and 2x times on 6-argument method (doesn't matter if arguments are primitive or reference).
According to profilers data the reason is the following:
- Call chain for reflective invocation looks as:
org.openjdk.reflect.MethodInvoke.invokeWithSixObjectParams()
java.lang.reflect.Method.invoke(...)
jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(...)
jdk.internal.reflect.GeneratedMethodAccessor1.invoke(...)
org.openjdk.reflect.MethodInvoke.staticMethodWithSixObjectParams(...)
- In pre-valhalla world all 3 intermediate methods were inlined and final invocation chain in code is:
reflect.MethodInvoke.invokeWithSixObjectParams()
reflect.MethodInvoke.staticMethodWithSixObjectParams(...)
- In valhalla only Method.invokewas inlined. Final invocation chain is:
org.openjdk.reflect.MethodInvoke.invokeWithSixObjectParams()
jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(...)
jdk.internal.reflect.GeneratedMethodAccessor1.invoke(...)
org.openjdk.reflect.MethodInvoke.staticMethodWithSixObjectParams(...)