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