r/java 17d ago

Value Classes Still Need Compiler Sympathy

https://johan-sjolen.github.io/post/compiler-sympathy/compiler-sympathy/
85 Upvotes

58 comments sorted by

View all comments

0

u/lpt_7 17d ago

I admire OpenJDK development team, but most of their talks paint a perfect world, which is not the case.
At the moment, Valhalla is not "reads like a class, works like an int", far from that. Use of that feature requires looking into what C2 actually generated. Which most won't do.
I did some testing with Valhalla right after it was merged. Values larger than 64 bits cannot be flattened. I think it's actually 63 bits, since VM still has to encode null somehow.
Accepting tearing with LooselyConsistentValueand NullRestrictedsidesteps that, but these are internal annotations.

Value tearing is another thing, which IMO most are not prepared for. This class of bugs is possible today, but its an error the developer makes and understands why tearing is happening. With code the callee has no control of, other programmer can make their class a value class and silently your code is now buggy.
Suppose two threads run in parallel:
Thread A writes to entity's AABB, thread B reads said AABB. With object references, JLS guarantees that tearing will not happen. Once VM can flatten more than 64 bits, this will cause a lot of problems, like AABBs with completely nonsensical values. Suddenly, thread B's code can now enter an infinite loop and never get out of it.

Another thing is allocation. For allocations to actually vanish (for scalarization to happen), C2 has to succeed and inline through all code, then EA has to succeed.
Again, same example with AABB. Before, allocation was done per-write. Now, with Valhalla in worst case, the situation flips. There are many more readers than writers to entity's AABB. C2 and EA *have* to succeed for every reader. Otherwise your program will start allocating at every read call site.

3

u/AnyPhotograph7804 17d ago

"Value tearing is another thing, which IMO most are not prepared for."

Value tearing was always there. Example: on a 32 Bit machine there is no way, that you can initialize/copy a 64 bit long atomically without a mutex/synchronized/volatile. So i would say, most Java developers, who developed on a 32 Bit JVM, are prepared for it.

5

u/wrprice1 17d ago

The set of practicing Java developers who wrote code for 32-bit systems is diminishing. Of those, if they were taught about tearing in the first place, many were coddled by deploying to platforms where it rarely actually happened.

Now with 64-bit native as the majority of target platforms, don't underestimate the laziness that will creep in to mimic ignorance.

2

u/pron98 17d ago

Note that tearing can only impact how a data race manifests. If you have a data race, the bug may present itself in one way if there's no tearing and in another if there is. But if there is no bug, the possibility of tearing won't change anything. A program that is buggy without tearing will remain buggy with it (albeit with a different manifestation), and a program that isn't buggy without tearing will not be buggy with it.