Daniel Sun created GROOVY-12284:
-----------------------------------

             Summary: Specialize indy sameClasses guards for arity 1-4
                 Key: GROOVY-12284
                 URL: https://issues.apache.org/jira/browse/GROOVY-12284
             Project: Groovy
          Issue Type: Improvement
            Reporter: Daniel Sun


h3. Problem

When an invokedynamic site is linked with all arguments non-null and at least 
one parameter type that is non-final (or a primitive wrapper — GROOVY-11782), 
{{Selector}} installs a same-class guard:

{code:java}
SAME_CLASSES
    .bindTo(expectedClasses)
    .asCollector(Object[].class, n)
    .asType(MethodType.methodType(boolean.class, pt));
{code}

{{asCollector}} of an {{Object}} array of length {{n}} allocates a fresh array 
on *every later invocation* of that site; the array overload of {{sameClasses}} 
then walks it.

That is the hot path for ordinary dynamic Groovy calls of the shapes 
{{recv.foo()}}, {{recv.foo(a)}}, {{recv.foo(a, b)}}, {{recv.foo(a, b, c)}} — 
arity 1-4 (receiver plus 0-3 arguments). Dynamic indy sites almost always have 
{{Object}} parameter types, so this guard is the common case, not a rare 
fallback.

(If any argument is {{null}} at link time, {{Selector}} already installs 
per-slot {{SAME_CLASS}} / {{IS_NULL}} tests and does not use the collector.)

The classic MOP already specializes this check: {{MetaClassHelper.sameClasses}} 
has overloads for 0-4 arguments so the call-site cache does not box arguments 
into an array. The indy guard did not.

h3. Goal

Keep the same guard semantics (return {{false}} if any argument is {{null}} or 
has a different runtime class) without allocating an {{Object}} array on the 
common 1-4 arity shapes.

h3. Approach

||Arity (incl. receiver)||Guard||
|0|constant {{true}}|
|1|existing {{SAME_CLASS}}|
|2|new {{SAME_CLASSES_2}}|
|3|new {{SAME_CLASSES_3}}|
|4|new {{SAME_CLASSES_4}}|
|5 or more|existing {{SAME_CLASSES}} plus {{asCollector}} (unchanged)|

Expected classes are bound with {{bindTo}}. One {{guardWithTest}} at the site, 
via a single {{Selector.sameClassesGuard(args, pt)}} helper.






--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to