acmp again !
john.r.rose at oracle.com
Thu Feb 21 00:56:56 UTC 2019
On Feb 20, 2019, at 4:37 PM, forax at univ-mlv.fr wrote:
> ----- Mail original -----
>> De: "John Rose" <john.r.rose at oracle.com>
>> À: "Remi Forax" <forax at univ-mlv.fr>
>> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
>> Envoyé: Jeudi 21 Février 2019 00:03:34
>> Objet: Re: acmp again !
>> On Feb 20, 2019, at 1:55 PM, forax at univ-mlv.fr wrote:
>>> I think we can agree that no solution will be perfect, you have to pick your
>>> 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.
> It doesn't match my experience, currently people have no expectation of what == means on a value type, if you explain that a value type has no identity, that == doesn't work on a value type, most people are ok with that. And because they are used to the fact that doing a == on Integers is like playing the Russian roulette, people do not bat an eye when i show the slide with acmp returning false, not being able to store null is a bigger issue.
Interesting data point. My inner mechanism purist is looking
for a straw to grasp at.
>> 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 will be harsh here because i don't share your optimism, we are introducing value types, departing from the comfy model of everything is an object, in part because countless hours have been spent trying to improve escape analysis to be more reliable. You are talking about the same kind of optimisations that will work great for some cases and not for others. Substituting an unreliable mechanism to an other unreliable mechanism doesn't look like a win.
And if there are no reliable mechanisms, you pick your poison.
So the paradoxical "always return false" is reliable, except that
it will produce an unpredictable amount of future confusion
to people who have been trained to expect a reflexive op==.
I.e., there are risks in every direction.
(Remi, I wish everyone were harsh like you. It would be a
>> 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.
> or better, to provide a direct replacement of the LIFE pattern, System.fastEquals(), that does an acmp if the arguments are references before calling equals i.e. get ride of LIFE instead of trying to emulate it by providing what people want which is a faster equals when possible. It's time to unplug LIFE from it life support and let it go :)
Well, that's what Objects.equals is, right? That's
the correct formula to use instead of writing out
the LIFE formula by hand.
(It's a better method than a LIFE sentence for
reforming wayward code.)
>> 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.
> these both methods are nice candidate for being (Java) compiler intrinsic, which is something i've already contemplated, instead of specifying that a record equals/hashCode and toString() should be desugared to invokedynamic, i think it's better to introduce three new methods structuralEquals, structuralHashCode, structuralToString in the API and say in the spec that for a record the generated equals/hashCode/toString are semantically equivalent to calling structuralEquals/structuralHashCode/structuralToString.
Ooh, I like this story. I'll gladly trade in "substitutability"
for "structural" if I can get a side order of toString.
>> (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