Thanks for the report and for the test case, Wenlei.
What you observe is an unfortunate consequence of LambdaForm
customization. It was introduced to speedup invocations of non-constant
method handles (MH.invoke/invokeExact on a method handle which isn't a
constant during JIT compilation).
As an example from your use case, in order to optimize for the value of
bound argument, the JIT compiler has to "see" it during the compilation.
The only way to achieve it right now is by issuing "specialized"
bytecode for the particular method handle and that's exactly what
happens during LambdaForm customization.
The generated class should go away once the method handle it was
generated for becomes unreachable, but it seems you construct plenty of
method handles for every query.
As a workaround, you can turn it off by specifying:
-Djava.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD=-1
But I agree with Remi that it's a sign of a deeper problem in how you
use method handles. MH.bindTo() always produces a new method handle and
doesn't look like a good fit for implementing lambda capturing.
Method handles are designed for fast invocation. Some non-trivial amount
of work happens during method handle instantiation, so it should be
avoided in hot code. From performance perspective, one-time usage of
method handles never pays off. You should try to cache and reuse them in
order to observe speedups.
In particular, reusing the same method handle chain for all rows and
passing the value (from the table) explicitly should lead to a better
generated code.
Best regards,
Vladimir Ivanov
On 5/2/17 10:29 PM, Wenlei Xie wrote:
Hi,
We are implementing Lambda function with capture support in a SQL
Engine. We currently implement by compiling user-written Lambda
Expression into a MethodHandle. And use bindTo to captured fields. Thus
for each row we will have a Bound Method Handle.
However, we found JVM will generate the byte code Bound Method Handle
once it's invoked more than 128 times. This cause in some cases (when
the table has large arrays), the Metaspace fills with generated
LambdaForm$BMH class.
Here is the simple code to reproduce the
issue: https://github.com/wenleix/BMHTest . It looks we cannot increase
java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD beyond 128. Any
suggestions to implement Lambda with Capture Support on JVM?
Thank you !!
Best,
Wenlei
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev