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

Reply via email to