Scott Murphy Heiberg created GROOVY-12488:
---------------------------------------------
Summary: SC: constructor reference calls the constructor through
the meta-class instead of directly
Key: GROOVY-12488
URL: https://issues.apache.org/jira/browse/GROOVY-12488
Project: Groovy
Issue Type: Improvement
Components: Static compilation
Affects Versions: 6.0.0
Reporter: Scott Murphy Heiberg
Under {{@CompileStatic}}, a constructor reference such as {{Made::new}} is
implemented by a synthetic method {{ctorRef$<method>$<n>}} on the enclosing
class, which the LambdaMetafactory call site targets. That method is not
statically compiled:
{noformat}
private static final Made ctorRef$ctorRef$0();
0: ldc class Made
2: invokedynamic init:(Ljava/lang/Class;)Ljava/lang/Object;
7: invokedynamic cast:(Ljava/lang/Object;)LMade;
12: areturn
{noformat}
So every call selects the constructor through the meta-class at run time, while
other method references ({{String::length}}, {{Math::abs}}) link their target
directly. In a GraalVM native image the constructor also needs reflection
metadata although the code is statically compiled.
The cause is
{{StaticTypesMethodReferenceExpressionWriter.addSyntheticMethodForConstructorReference}}:
it builds the constructor call without a target constructor and sets
{{STATIC_COMPILE_NODE}} to false (there is a TODO for it).
Proposed fix: select the constructor at compile time from the functional
interface's parameter types, as for a constructor call expression, and call it
directly. Keep the run-time selection when no single constructor matches
(GROOVY-10971) and for a protected constructor in another package. As with
other method references and with Java, the constructor is then chosen from the
declared parameter types rather than the run-time argument types.
PR: https://github.com/apache/groovy/pull/3022
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)