Thank you Vladimir for the help ! I see the point why MH.bindTo() is not a
good fit for implementing lambda capturing.

We cannot easily directly pass the values from table explicitly to the
generated MethodHandle, as we allow UDF/extract function used in lambda
functions.

I see Brain talked about use InvokeDynamic to implement Java lambda capture
(http://wiki.jvmlangsummit.com/images/7/7b/Goetz-jvmls-lambda.pdf) and the
LambdaMetaFactoryBenchmark class, I did some benchmark and it seems to have
better performance for capture support :). However I do see some strange
performance regression after the invocation number exceeds some threshold,
which is probably better fit in a separate email thread :)

Best,
Wenlei

On Wed, May 3, 2017 at 5:34 AM, Vladimir Ivanov <
vladimir.x.iva...@oracle.com> wrote:

> 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
>



-- 
Best Regards,
Wenlei Xie (谢文磊)

Email: wenlei....@gmail.com
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to