Status Update
Comments
zm...@gmail.com <zm...@gmail.com> #2
Also crashes in R8 version 8.5.35, 8.6.17, 8.7.2-dev
ch...@google.com <ch...@google.com> #3
You cannot apply keep rules for classes synthesized by R8, but if you keep the implemented interfaces, the merging should not happen.
That said, checking the implementing class of a lambda might not be a good idea. The specification for java.lang.invoke.LambdaMetafactory
Capture may involve allocation of a new function object, or may return a suitable existing function object. The identity of a function object produced by capture is unpredictable, and therefore identity-sensitive operations (such as reference equality, object locking, and System.identityHashCode()) may produce different results in different implementations, or even upon different invocations in the same implementation.
If I understand this correctly the only guarantee is that the function object implements the interface(s) specified.
Description
A given startup profile may miss methods, for example, due to the startup profile being stale or due to limitations in the startup profile generation.
R8 could help mitigate this by automatically inferring which methods must be startup methods and including these in the startup profile.
Example rules:
If a method is a startup method, then the class initializer of the method's class must also be a startup method.
If a startup method is only called from a single context, then the context must also be a startup method.
If a static field is accessed unconditionally a startup method, then the class initializer of the field's class must also be a startup method. (A similar rule can be added for invokes to static methods.)
A static field is accessed unconditionally if the field instruction reverse dominates the method entry, i.e., the method entry is guaranteed to execute the field instruction (assuming no exceptions arise).