JDK-8215649 : remove equals and hashCode implementations from j.l.i.VarHandle
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 12
  • Submitted: 2018-12-19
  • Updated: 2019-01-11
  • Resolved: 2019-01-11
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Remove the implementations of methods VarHandle::equals and VarHandle::hashCode, added in 12, in order to make j.l.i.VarHandle implementation consistent with j.l.i.MethodHandle.

Problem
-------

It is not possible to make sure that two VarHandles with the same content are equal, so we prefer to make no assumptions and don't override the default implementation at j.l.Object.  These methods were erroneously added in 12 and should be backed out before 12 ships.  

Solution
--------

Remove the implementations provided as part of JEP-334 [1]

Specification
-------------

    diff -r 9b0d6ecd8e45 -r 26cf6ea754d2 src/java.base/share/classes/java/lang/invoke/VarHandle.java
     --- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed Dec 19 14:02:19 2018 -0500
    +++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed Dec 19 14:28:06 2018 -0500
    @@ -1865,35 +1865,6 @@
         }
    
         /**
    -     * Compare this {@linkplain VarHandle} with another object for equality.
    -     * Two {@linkplain VarHandle}s are considered equal if they both describe the
    -     * same instance field, both describe the same static field, both describe
    -     * array elements for arrays with the same component type, or both describe
    -     * the same component of an off-heap structure.
    -     *
    -     * @param o the other object
    -     * @return Whether this {@linkplain VarHandle} is equal to the other object
    -     */
    -    @Override
    -    public final boolean equals(Object o) {
    -        if (this == o) return true;
    -        if (o == null || getClass() != o.getClass()) return false;
    -
    -        VarHandle that = (VarHandle) o;
    -        return accessModeType(AccessMode.GET).equals(that.accessModeType(AccessMode.GET)) &&
    -               internalEquals(that);
    -    }
    -
    -    abstract boolean internalEquals(VarHandle vh);
    -
    -    @Override
    -    public final int hashCode() {
    -        return 31 * accessModeType(AccessMode.GET).hashCode() + internalHashCode();
    -    }
    -
    -    abstract int internalHashCode();
    -
    -    /**
          * Returns a compact textual description of this {@linkplain VarHandle},
          * including the type of variable described, and a description of its coordinates.
          *

References
-------------
* [1] https://bugs.openjdk.java.net/browse/JDK-8203252
* webrev: http://cr.openjdk.java.net/~vromero/8215648/webrev.00/
Comments
thanks for the approval
11-01-2019

Moving to Approved.
11-01-2019

It was a mistake to add those methods in the first place. While in the simple cases, such as a direct VarHandle that describes a field, it is easy to determine if two VHs are direct VHs for the same field. However, in the general case, it is not so simple. For example, there are combinators on VHs to say ���the behaviour of that other var handle, but with volatile.��� When applying combinators in sequence, it may be possible to arrive at results that are functionally equivalent, but were composed with different paths. MethodHandle has traversed this ground already, and decided that it is better to simply use object identity; VarHandle should behave similarly.
10-01-2019

CSR for the addition of the methods in question included as part of JDK-8202031. Can you please describe more the motivation for this change? I assume the equality/ineqaulity can be determined easily in some cases, but is intractable in others. Moving to Provisional.
09-01-2019