--- old/src/java.base/share/classes/java/util/HashMap.java 2015-01-10 13:43:10.228150302 +0100 +++ new/src/java.base/share/classes/java/util/HashMap.java 2015-01-10 13:43:10.107152713 +0100 @@ -25,6 +25,9 @@ package java.util; +import sun.misc.JavaLangAccess; +import sun.misc.SharedSecrets; + import java.io.IOException; import java.io.InvalidObjectException; import java.io.Serializable; @@ -339,23 +342,44 @@ } /** + * Function returning TRUE for given Class when it is safe to compare + * instances of it among themselves. + */ + private static final Function, Boolean> isSelfComparableClass = + new Function, Boolean>() { + @Override + public Boolean apply(Class c) { + Type[] ts, as; ParameterizedType p; + if ((ts = c.getGenericInterfaces()) != null) { + for (Type t : ts) { + if ((t instanceof ParameterizedType) && + ((p = (ParameterizedType) t).getRawType() == + Comparable.class) && + (as = p.getActualTypeArguments()) != null && + as.length == 1 && as[0] == c) // type arg is c + return Boolean.TRUE; + } + } + return Boolean.FALSE; + } + }; + + /** * Returns x's Class if it is of the form "class C implements * Comparable", else null. */ static Class comparableClassFor(Object x) { if (x instanceof Comparable) { - Class c; Type[] ts, as; ParameterizedType p; - if ((c = x.getClass()) == String.class) // bypass checks + Class c; + if ((c = x.getClass()) == String.class) { // bypass checks + return c; + } + JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); + Boolean scc = (jla != null) + ? jla.getGenericDerivative(c, isSelfComparableClass, isSelfComparableClass) + : isSelfComparableClass.apply(c); // in case very early in boot-up sequence + if (scc != null && scc) { return c; - if ((ts = c.getGenericInterfaces()) != null) { - for (Type t : ts) { - if ((t instanceof ParameterizedType) && - ((p = (ParameterizedType) t).getRawType() == - Comparable.class) && - (as = p.getActualTypeArguments()) != null && - as.length == 1 && as[0] == c) // type arg is c - return c; - } } } return null;