Equality for values -- new analysis, same conclusion
Brian Goetz
brian.goetz at oracle.com
Mon Aug 12 18:34:01 UTC 2019
>
> (Shorter: benchmarks, please?)
+1.
I'll let Sergey answer in more detail here, since he's closest to it,
with the caveat that we've not really tried to optimize the
substitutibility test in the JIT. The biggest concern is not so much
that new code will suffer, but that old code which never knew about, and
will never care about, values will suffer. (Much of this can be
mitigated by aggressive speculation, but this is not free either.)
>
>> On Aug 10, 2019, at 12:57 PM, John Rose <john.r.rose at oracle.com
>> <mailto:john.r.rose at oracle.com>> wrote:
>>>
>>> - As a fast path for deeper equality comparisons (a == b ||
>>> a.equals(b)), since the contract of equals() requires that ==
>>> objects are equals().
>>
>> This is what I call L.I.F.E., the Legacy Idiom For Equality. ID== is
>> good here too. FAST== would be fine here, and a JIT could perform
>> that strength reduction if it notices that the == expression is
>> post-dominated by Object.equals (on the false path). I think that’s
>> usually detectable.
>>
>
> Major caveat for this kind of optimization: it relies on a
> "well-behaved" 'equals' method. If 'equals' can thrown an exception or
> have some other side effect (even indirectly) when a == b, we can't
> just blindly execute that code.
>
> Maybe the optimization you envision is able to cope with these
> possibilities. JIT is a mystery to me. But it seems like something
> that needs careful attention.
>
I believe much of the "is this legal" ground here has been covered by
previous attempts to intrinsify various methods (though this would
probably the first time we apply this reasoning to user-overridable
methods.) Essentially, this would be using invariants of the
specification to enable certain transformations. Specifically, the
specification
https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object)
clearly says that for a non-null reference x, x.equals(x) must be true.
Can we use that to optimize `x==y || x.equals(y)`? I can see the
arguments on both sides.
More information about the valhalla-spec-observers
mailing list