deduplicating lambda methods

B. Blaser bsrbnd at gmail.com
Wed Mar 28 21:51:39 UTC 2018


On 28 March 2018 at 20:09, Maurizio Cimadamore
<maurizio.cimadamore at oracle.com> wrote:
>
>
> On 28/03/18 18:58, B. Blaser wrote:
>>
>> On 28 March 2018 at 19:44, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com> wrote:
>>>
>>> Uhm - seems to me that the currently implemented logic is more subtle
>>> than
>>> comparing symbols by name in the visitIdent case? E.g. it (correctly)
>>> uses
>>> information about the relative position of a lambda parameter in the
>>> parameter list and compares that instead of names. And visitSelect is
>>> correctly doing a == on the accessed symbol, so that
>>>
>>> class Foo { String x; }
>>>
>>>
>>> (Foo a) -> a.x
>>>
>>> (Foo b) -> b.x
>>>
>>> are deemed equal because:
>>>
>>> (i) - a and b have same positional info
>>> (ii) - a.x and b.x refer to the same (==) symbol (Foo::x)
>>
>> I missed this e-mail but I just sent 5 minutes ago the full patch
>> which preserve relative positions of lambda parameters, of course.
>> If you try the two examples I sent previously without the patch,
>> you'll see that:
>>        r1 = () -> {
>>            Class<?> c = Integer.class;
>>        };
>>
>> isn't de-duplicated because occurrences of Integer.class aren't '==' and:
>>
>>        r1 = () -> {
>>            Runnable r2 = () -> {};
>>        };
>>
>> isn't de-duplicated because calls to lambda meta-factory aren't '=='.
>
> To me this seems to suggest that, if we want to get better results out of
> the dedup machinery, we have to up our lowering game, so that we don't do
> excessive generation of fresh symbols. Right now we don't cache .class
> symbols and also metafactory calls with same static args and BSM - and
> that's the problem you are seeing, I believe.

You're right. The fix below tries to cache meta-factory calls, solving
the following de-duplication problem:
    r1 = () -> {
        Runnable r2 = () -> {};
    };

Bernard

diff -r 9925be430918
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
   Wed Mar 28 14:24:17 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
   Wed Mar 28 23:24:59 2018 +0200
@@ -226,6 +226,8 @@

         private Map<DedupedLambda, DedupedLambda> dedupedLambdas;

+        private Map<Name, DynamicMethodSymbol> dynMethSyms = new HashMap<>();
+
         /**
          * list of deserialization cases
          */
@@ -1220,7 +1222,8 @@
                                             staticArgs.toArray());

             JCFieldAccess qualifier =
make.Select(make.QualIdent(site.tsym), bsmName);
-            qualifier.sym = dynSym;
+            DynamicMethodSymbol existing =
kInfo.dynMethSyms.putIfAbsent(methName, dynSym);
+            qualifier.sym = existing != null ? existing : dynSym;
             qualifier.type = indyType.getReturnType();

             JCMethodInvocation proxyCall = make.Apply(List.nil(),
qualifier, indyArgs);

> Maurizio
>
>>
>> Bernard
>>
>>> Maurizio


More information about the amber-dev mailing list