Top
Best
New

Posted by philonoist 12 hours ago

Project Valhalla, Explained: How a Decade of Work Arrives in JDK 28(www.jvm-weekly.com)
444 points | 251 commentspage 2
cogman10 4 hours ago|
> There’s a catch worth knowing about here, though: flattened data has to be readable and writable atomically (otherwise it risks “tearing” under concurrent access).

I really hope they give an escape hatch for this. It will make it really hard to extract a lot of the benefit of valhala if you can't make a thread unsafe value class. It's also one of those problems that will be quite hard to run into. You basically need something like this

    class Bar {
      static Foo value[] = new Foo[10];
      static void setFooFromManyThreads(Foo foo) {
        value[0] = foo;
      }
      
      value record Foo(int x, int y, int z) {};
    }
Not something you typically run into and generally already a thread safety problem.

The solution is also simple, a `synchronized{}` block will fix it if you need to have a tearable class that's written from multiple threads.

But the other thing is that for SIMD operations, you really need flattening, and that really does typically mean having something like `Foo(double x, double y, double z)` in play. It'd be a shame if the way we have to do this is a struct of arrays.

spbaar 7 hours ago||
I have such an urge to comment "lgtm" on the 197k line change PR
arein3 5 hours ago|
Do it
leiroigh 9 hours ago||
I'll be interested in seeing the fallout of the (unavoidable) compat issue:

If I have a function that has a value `x` that erases to `java.lang.Object` (e.g. a parametric function with no lower bound); then it used to be safe to check for nullity and then synchronize on the object.

This is no longer safe: This can now throw `IdentityException` into your face. (it was _never_ a good idea)

In other words, a lot of old code must be reviewed.

I suspect that `-XX:DiagnoseSyncOnValueBasedClasses=2` will need to stay (with the semantics: if user tries to synchronize on identity-less object, then log a JFR event and make it a NOP, don't throw an exception)!

The current JEP text is a little too ambiguous to figure out whether that is the plan, anyways.

watt 7 hours ago|
You lost me at "I have a function that has a value `x`". How does function "have" a value?
porridgeraisin 6 hours ago||
I think they meant function that takes a value x as an argument.
vlovich123 5 hours ago||
> Before we pop the champagne, though: this is preview, disabled by default, and, as Brian Goetz was quick to cool everyone down, “only the first part of Valhalla.” Goetz added a great observation that the “they’ll never ship it” crowd will now smoothly switch over to “but they didn’t ship the most important part” (and a joke has been going around the community for years that we’ll sooner end up in Valhalla ourselves, the Norse-afterlife one, than the project ships).

I don’t know if this is fair way to try to disarm your critics. The only thing that’s remained after this decade is the slogan so it’s a real ship of Theseus question if Valhalla has shipped since what’s delivered doesn’t achieve it. Congrats on the accomplishment, but from looking at what ended up, I’m not sure it’s a huge improvement.

> The trouble is that this optimization is unpredictable and fragile.

Is this describing escape analysis or value classes? Because the list of exclusions where this does anything is so large and the conversion to a heap type under the hood is so transparent and opaque, I think it can describe this technique as well.

Also, the whole “works like an int” motto is violated - int is never null, int-> integer boxing is explicit and well understood.

> In the new model, the wrapper classes themselves become value classes (when preview is on, Integer, Long, Double, and company lose their identity

Oh neat, they sidestep that by changing the definition of an int. I’m sure it’ll be trivial to turn this on in the wild on code that may be relying on identity for boxed numerics. I think this alone shows this project can’t ever be turned on by default and now we’ll have a decade of two Java languages (one with value types and one without) as they try to convince everyone to migrate and then just turn it on (ie python3).

So much opportunity squandered and dismissing critics as always having something to complain about is a neat way to sidestep legitimate criticism that this approach is not going to work out for Java.

narag 4 hours ago||
I found a solution for what seems to be the same problem, in a different language: a particular type of lists, where the class metadata is stored once and the data for each instance is contiguously stored in a flat array.

Not sure if it covers exactly the same terrain, but perusing the article, it seems to be the case, with a single instance being the degenerate case.

cogman10 3 hours ago|
Yup, it's the same terrain.

I've made something like this in the past. And I did it exactly because `List<Foo>` was too expensive and slow.

    class FooSOA extends Collection<Foo> {
      double x[];
      double y[];
      double z[];
      
      Foo get(int index) { return new Foo(index); }
      
      record Foo(int index) {
        double x() { return FooSOA.this.x[i]; }
        double y() { return FooSOA.this.y[i]; }
        double z() { return FooSOA.this.z[i]; }
      }
    }
minitech 5 hours ago||
> How is this different from struct in C#? A struct in C# has identity

Since when? I’m pretty sure structs didn’t have identity last time I used C#, and that would be a very surprising thing to add.

Alexander-Barth 10 hours ago||
I think this is quite similar to julia's handling of a struct. An array of mutable structs is just an array of pointers, where every pointer directs to the underlying structure. However with an array of structs (immutable is the default), there is no such indirection. The value of all fields are stored as array element (unless you have an array of heterogeneous elements).

If you want to change an element of such an array you need to create a new immutable struct which in practice it is quite fast, but a bit verbose to write.

exabrial 5 hours ago||
Tons of armchair critics but dang this is freaking cool!!! Thanks everyone for working on this an THANK YOU for moving slow and getting the design right!
newsoftheday 4 hours ago||
I just got my projects up to JDK 21 a few months ago. Working on trying to get one upgraded to JDK 25 now and now they're talking about delivering JDK 28 in less than a year from now. How are you supposed to keep up with these rapid updates?
jeroenhd 2 hours ago||
JDK 21 is a few years old now, so you were a few years behind. JDK 25 was released last year, which makes for the next stable LTS for a while. JDK 28 is expected in 2028, and these features are not going to be enabled by default for years after that.

Java is generally backwards compatible, so unless you're using fat frameworks that use shady internals or known-deprecated APIs, you should generally be fine immediately upgrading to the latest LTS, possibly even non-LTS versions if you have confidence in your stack.

cogman10 4 hours ago|||
What did you go from to get to 21?

Mostly just hit the LTSes is what we've been doing and since about 17 it's been a pretty easy process in general.

Protip: If you ditch lombok everything gets a lot easier.

bpodgursky 3 hours ago||
How much stuff actually broke? I feel like you can treat Java upgrades as minor upgrades most of the time, maybe you have to rebuild a few binaries but I'd be shocked if it required significant code changes.
maelito 7 hours ago|
What I have in mind when I read Valhalla : https://valhalla.openstreetmap.de/
More comments...