Skip to content

Conversation

jchyb
Copy link
Contributor

@jchyb jchyb commented Sep 29, 2025

Just a few small tweaks left:

  • extract MethodHandles.lookup into local variable in the static constructor
  • [x] maybe inline objCAS2 (should give us more freedom, allow us to backport into 3.3 in the worst case scenario (hopefully not))
    EDIT: done

This PR replaces the use of the deprecated Unsafe with VarHandles, available in java 9+. Important thing about VarHandles is that for private members (like our val dictating the value/resolution progress of the lazy val), the findVarHandle method must be called from the class containing the val, otherwise we end up with an error. This meant that some custom logic had to be added to the MoveStatics phase, which would usually move static constructor to the companion object (which we do not want for the VarHandles here).
Only the newer implementation was adjusted, the one available under -Ylegacy-lazy-vals was left untouched.

This PR also effectively drops support for java 8, with java 17 being the new required version. As part of that:

  • lowest supported version for -release/-java-target-version is now 17 (earlier versions will throw an error). -Xunchecked-java-output-version was left untouched.
  • managed community-build tests are now run with java 17. Options setting -release 8 were removed for projects that were using that. Projects that were using javax.xml.bind (dropped in java 11) were removed altogether (playJson and betterfiles)
  • Java version used for releases was set to 17

@jchyb jchyb force-pushed the lazyval-varhandle branch 5 times, most recently from a82a297 to 5aafc89 Compare October 2, 2025 14:32
@sjrd
Copy link
Member

sjrd commented Oct 3, 2025

extract MethodHandles.lookup into local variable in the static constructor

I actually wonder: is that worth it? It seems to bring additional complexity to the transformation. Sure, we need one call for every lazy val in the class, but does it matter? It's in the static initializer anyway, which is executed O(1) times.

maybe inline objCAS2

IMO that is really worth it, but for a different reason: it removes the last reference to the LazyVals$ module class in the generated code. That's good because we are then reasonably sure that we won't hit load-class-time warnings about the Unsafe val in that module class. AFAICT, generating the inlined code would not be any harder than generating the call to objCAS2. It's one method call.

(We can drop the if (debug) thing at this point anyway.)

@jchyb
Copy link
Contributor Author

jchyb commented Oct 3, 2025

extract MethodHandles.lookup into local variable in the static constructor

I actually wonder: is that worth it? It seems to bring additional complexity to the transformation. Sure, we need one call for every lazy val in the class, but does it matter? It's in the static initializer anyway, which is executed O(1) times.

It's an obvious improvement so I wanted to take it. Unfortunately, even without this we still had to introduce complexity in the MoveStatics phase (directly linking to the LazyVals phase), so we are not doing that much more (1st commit vs 2nd commit). I'll try running some benchmark tests to see if it's worth it.

maybe inline objCAS2

IMO that is really worth it, but for a different reason: it removes the last reference to the LazyVals$ module class in the generated code. That's good because we are then reasonably sure that we won't hit load-class-time warnings about the Unsafe val in that module class. AFAICT, generating the inlined code would not be any harder than generating the call to objCAS2. It's one method call.

(We can drop the if (debug) thing at this point anyway.)

Right, I hadn't even thought about that (we still reference the nested classes but now I realize that's not an issue). Weirdly, even with the objCAS2 call, the warnings disappeared for me.

@jchyb jchyb force-pushed the lazyval-varhandle branch from 5aafc89 to 74429df Compare October 5, 2025 18:43
@jchyb jchyb force-pushed the lazyval-varhandle branch 4 times, most recently from a35121d to 9032701 Compare October 6, 2025 15:47
@jchyb jchyb force-pushed the lazyval-varhandle branch from 9032701 to bb1b2ca Compare October 6, 2025 18:07
@jchyb jchyb marked this pull request as ready for review October 7, 2025 09:15
@jchyb jchyb requested a review from sjrd October 7, 2025 09:15
@jchyb
Copy link
Contributor Author

jchyb commented Oct 7, 2025

@sjrd Issues with CI took me a little more time than I anticipated, so I haven't done the promised benchmarks yet. Still I am willing to remove the initialization optimization if it complicates things too much.

I did test whether this works with native image though (it does).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants