deduplicating lambda methods
maurizio.cimadamore at oracle.com
Mon Mar 5 13:40:51 UTC 2018
On 05/03/18 11:49, Tagir Valeev wrote:
> By the way how types are matched? I assume that you won't
> merge `s -> s`
> and `x -> x`
> if `s` is String and `x` is an int, right? However merging two
> lambdas like
> `s -> true` and `sb -> true`
> where `s` is a String and `sb` is a StringBuilder seems
> possible (creating
> a synthetic method which
> receives an Object).
> Yes, if parameters are unused, then I'd expect that an AST diff
> will just say that the body is the same for both.
> What if unused parameter have different primitive type or primitive
> and object type? Will we tolerate unnecessary boxing? Well, it's
> possible just to drop an unused parameter from synthetic method
> declaration, though this might require changes in LMF. Also in this
> case we will not see the variable in debugger.
> This reminds me about (postponed?) lambda leftovers JEP. Probably if
> that JEP will be implemented, duplication should ignore underscore
> parameters only. In this case absence in debugger is not a problem.
Note that, from an implementation perspective, we could even drop the
unused parameter from the synthetic lambda body entirely and use some
kind of MH adaptation to inject a default one in there (based on the
'invokedType') - so, yes, this is a problem, and we might restrict the
level of deduplication in case of primitive vs. reference clashes, but
maybe there are technical solutions to address that one too. Of maybe we
just want to wait to handle those for when we have better value support
(see L-world effort in valhalla) :-)
> Also two lambdas like `list -> list.size()` can be
> merged if the parameter types
> differ in type parameters (e.g. List<String> and
> List<Integer>), but have
> the same erasure.
> Yes, the diff should work on erased types, which is what really
> matters in terms of bytecode generation. There are of course
> caveat - if you call List::get instead of List::size, then you can
> get extra synthetic casts, and, in that case, you need to avoid
> deduplication so that each lambda can have its own synthetic cast.
> On Mon, Mar 5, 2018 at 10:59 AM, Liam Miller-Cushon
> <cushon at google.com <mailto:cushon at google.com>>
> On Fri, Mar 2, 2018 at 8:01 PM, Vicente Romero
> <vicente.romero at oracle.com <mailto:vicente.romero at oracle.com>>
> 1) How to identifying duplicates: I have a prototype
> that runs during
> lambda desugaring and identifies duplicates by
> diffing ASTs. Is that the
> best place for deduplication, or it worth
> considering comparing
> code instead of ASTs?
> are you doing an exact diff? I assume that we want: s
> -> s to be equal to
> z -> z provided that the target is the same
> Lambda parameters are currently handled as a special case.
> The diff tests
> that the syntax for the two trees is the same, and that
> the symbols
> associated with identifier and select nodes are
> equivalent. It accepts
> symbols that correspond to the same parameter in each of
> the associated
> lambda methods.
> E.g. when diffing the lambda bodies for `s -> s` and `x ->
> x` it sees that
> `s` and `x` are both the first parameter of their
> enclosing lambdas.
More information about the amber-dev