acmp again !

John Rose john.r.rose at
Wed Feb 20 23:03:34 UTC 2019

On Feb 20, 2019, at 1:55 PM, forax at wrote:
> I think we can agree that no solution will be perfect, you have to pick your poison.
> And yes, always returning false is perhaps the lesser evil after all.

Yep, at this point we are picking poisons, not cherries.

Returning false (either always, or after some cutoff rule)
breaks the very fundamental property of reflexivity.

Though that's my preference from a "mechanism purist"
point of view, it will please only would-be mechanism
purists like me.  The other 90% of our community will
be rubbing our nose in puzzlers and other "those idiots"
blog entries, basically forever.

The other alternative is to push the expense of a
substitutability test into acmp and op==.  This will
please "semantics purists" (which I can be also), and
displease only those people who happen to run over
the performance potholes.  We don't have any proof
that those potholes will be significant; what we do
have is many ideas for working around those problems
if they should occur.  It feels like making acmp
potentially expensive also entails making it
potentially *inexpensive* again also, at the cost
of some engineering in the JVM and JDK.

Many uses of acmp which will turn into a
substitutability test are (we think) in generic
code which is using runtime typing and is
reused for a range of different types, some
values and some classic references.  You
could probably write a book on how such
codes are optimized today, and most of the
existing techniques that provide necessary
devirtualization would also solve for expensive

I think also we will want to bake into the JVMS
some kind of permission to strength-reduce acmp
with a nearby Object.equals call, by making equals
into a semi-intrinsic that the JVM can reorder
and merge with acmp.  Reflexivity of equals
is in the javadoc but not in the JVMS and so
JITs don't make use of it now.  But they might
want to if acmp became a subject of optimization.

Another idea we may wish to play with is an API
point which provides the fixed-cost approximate
equality test that acmp provides today.  It would
not be acmp but rather something with a name
like "System.fastSubstitituabilityTest".  Programmers
of sophisticated libraries could use this as an
alternative component to the famous LIFE
(Legacy Idiom For Equality).  The Objects.equals
API point, for example, would convert to a new
LIFE instead of remaining stuck in its old LIFE.
(We could spend a LIFE-time punning about this.)

So the proposed System.isSubstitutable would
be implemented as "return x==y", using the
slow-but-steady acmp instruction, while the
other thing would be an intrinsic native method,
with complicated weasel words in its spec.

Where there's an equals there's a hash code, so…

Next Question:  Should System.identityHashCode
throw an exception, return zero, or do a deep
hash code when presented with a value instance?
Since it's a niche function used by experts, maybe
the surprising behavior of throwing an exception
is permissible, where making op== non-reflexive
would surprise everyone.  I do believe we want a
new API point System.substitutabilityHashCode
so that code can truly and explicitly opt into
processing that aspect of value types, rather than
getting accidental results from System.iHC.

(Oh, and also the JVM gets to pick the hash code
here, not the JDK.  Let's not proliferate base-31
hashing any further, please.  This is a vectorizable
operation, so hardware should determine the fastest
good hash, in any particular run of the JVM.  As
folks know, I'm talking about moderns hashes
based on high-precision multiply, AES-step, etc.)

— John

More information about the valhalla-spec-experts mailing list