Scott Murphy Heiberg created GROOVY-12492:
---------------------------------------------
Summary: Static compilation converts closure literals to
functional interfaces through a runtime proxy
Key: GROOVY-12492
URL: https://issues.apache.org/jira/browse/GROOVY-12492
Project: Groovy
Issue Type: Improvement
Components: Static compilation
Affects Versions: 6.0.0
Reporter: Scott Murphy Heiberg
Under {{@CompileStatic}}, a closure literal whose target is a functional
interface is still compiled to a {{Closure}} subclass and converted at run
time. That covers a literal passed to a SAM parameter, assigned or returned as
a SAM type, cast with {{(SAM)}}, or coerced with {{as SAM}}. For example:
{code:groovy}
@CompileStatic
int sum(int n) { IntStream.range(0, n).reduce(0) { int a, int b -> a + b } }
{code}
compiles to {{invokedynamic
cast:(Lgroovy/lang/Closure;)Ljava/util/function/IntBinaryOperator;}}, and {{\{
... \} as IntBinaryOperator}} to an {{asType}} call. At run time,
{{CachedSAMClass.coerceToSAM}} / {{TypeTransformers.createSAMTransform}} create
a {{java.lang.reflect.Proxy}} with a {{ConvertedClosure}} handler, and each
call goes through the proxy and {{Closure.call(Object...)}}. The same code
written as a lambda uses {{LambdaMetafactory}}.
Consequences: the proxy and reflective dispatch cost on every call, and in a
GraalVM native image each interface must be registered as a proxy, otherwise
the statically compiled conversion fails with {{GroovyCastException}}.
Proposal: an incubating {{groovy.target.closure.sam}} compiler option, off by
default, that converts such literals at compile time with a generated adapter
class that behaves as the proxy does.
PR: https://github.com/apache/groovy/pull/3026
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)