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