The static method Objects.equals(Object,Object) emulation has a non-standard overload equals(String,String), intended to capture via Java's standard compile time polymorphism. This is great when the two arguments are declared to be Strings in the original Java source, but GWT already has a mechanism to pick a more specialized method, and it can kick in after a few rounds of compilation, allowing a variable declared as Object but always assigned to a String value to take advantage of this.
Additionally, this would make it possible for generated record type equals(Object) methods to automatically dispatch to the expected String specialization without having to statically look up the correct implementation.
We can't just rename equals(String,String) to equalsString(String,String) and add the @SpecializeMethod annotation on equals(Object,Object) as SpecializeMethod's javadoc notes:
|
* The annotated method must call the target method directly, and the compiler |
|
* must not inline the target method to prevent it from being pruned while it |
|
* still might be used. |
This is a new note that I added recently as part of solving another bug, see #10165 / #10055. Applying this requirement would increase compiled size of equals(Object,Object) by adding an extra unpruneable instanceof - so while this is possible, it probably isn't the best plan.
The requirement exists so that the compiler is able to leave the specialization without pruning it because it still has at least one use. MethodInliner is already prevented from inlining away the original implementation until we're confident that the specialization cannot be applied. Then, we remove all specializations and prune one more time.
DeadCodeElimination performing constant folding through static method calls on constants also has a similar limitation (or at least ought to) - if the method is inlined away before DCE can examining the call to see if it applies to constants and can be computed at compile time, then the optimization cannot take place. #10255 is intended to improve this situation, and the draft fix works by marking certain method calls as capable of being statically evaluated, then uses the RemoveSpecializations pass to also remove that marker as well. This suggests that it might be worth also running MethodInliner again after specializations are removed, something also included in that draft.
The static method
Objects.equals(Object,Object)emulation has a non-standard overloadequals(String,String), intended to capture via Java's standard compile time polymorphism. This is great when the two arguments are declared to be Strings in the original Java source, but GWT already has a mechanism to pick a more specialized method, and it can kick in after a few rounds of compilation, allowing a variable declared as Object but always assigned to a String value to take advantage of this.Additionally, this would make it possible for generated record type equals(Object) methods to automatically dispatch to the expected String specialization without having to statically look up the correct implementation.
We can't just rename equals(String,String) to equalsString(String,String) and add the
@SpecializeMethodannotation on equals(Object,Object) as SpecializeMethod's javadoc notes:gwt/user/super/com/google/gwt/emul/javaemul/internal/annotations/SpecializeMethod.java
Lines 26 to 28 in 3caf879
This is a new note that I added recently as part of solving another bug, see #10165 / #10055. Applying this requirement would increase compiled size of equals(Object,Object) by adding an extra unpruneable
instanceof- so while this is possible, it probably isn't the best plan.The requirement exists so that the compiler is able to leave the specialization without pruning it because it still has at least one use. MethodInliner is already prevented from inlining away the original implementation until we're confident that the specialization cannot be applied. Then, we remove all specializations and prune one more time.
DeadCodeElimination performing constant folding through static method calls on constants also has a similar limitation (or at least ought to) - if the method is inlined away before DCE can examining the call to see if it applies to constants and can be computed at compile time, then the optimization cannot take place. #10255 is intended to improve this situation, and the draft fix works by marking certain method calls as capable of being statically evaluated, then uses the RemoveSpecializations pass to also remove that marker as well. This suggests that it might be worth also running MethodInliner again after specializations are removed, something also included in that draft.