On Wed, 15 Jul 2026 19:35:18 GMT, Jorn Vernee <[email protected]> wrote:
> The methods `load()`, `unload()`, `isLoaded()`, and `force()` in > `MemorySegment` currently delegate to `ScopedMemoryAccess` through a set of > `@Scoped` methods, after which the implementation calls into > `java.nio.MappedMemoryUtils`. This means that, when a shared scope is closed > during a call to one of these methods, an exception can be installed at any > point during the execution of the util method. > > The problem is that some parts of these methods are not able to handle such > exceptions being installed. > > We've had some previous discussion about these methods not really needing to > be `@Scoped` in the first place, but instead being able to rely on paired > acquire/release of the session being accessed. This code is not as > performance critical compared to a scoped memory access, since we're doing a > native call any way. > > To avoid issues with exceptions being installed in surprising places, this > patch switches the named methods to use acquire/release instead of being > `@Scoped`. This changes the behavior of these methods slightly: they now keep > the scope alive during the execution of the method. I've updated the doc, > borrowing from existing text in the `Linked::downcallHandle` docs, to explain > that a scope closure may now fail during the execution of one of these > methods. > > Does this seem like the right tradeoff? > > --------- > - [x] I confirm that I make this contribution in accordance with the [OpenJDK > Interim AI Policy](https://openjdk.org/legal/ai). I've applied the suggestion, and tested the generated output to make sure the links work. > Btw -- one possible way to make this work sort of "for free" would be to turn > load/force & co. into downcall handles (which they sort of are, as they are > implemented in native anyway). Then, the usual keep-alive mechanism for > downcalls would explain why these operations work the way they do. I don't think we can avoid amending the documentation for these methods either way, right? There is still an observable behavior change. Any way, I figured it would be nice to have a section on MemorySegment that explains that using a memory segment might block the scope from closing, as there are other operations that can behave this way when a segment is converted to a buffer, and the buffer is then used. src/java.base/share/classes/java/lang/foreign/MemorySegment.java line 1022: > 1020: * Determines whether all the contents of this mapped segment are > resident in physical > 1021: * memory. > 1022: * <p> Adjusting the format to match the rest of the docs while I'm here. src/java.base/share/classes/jdk/internal/misc/X-ScopedMemoryAccess.java.template line 241: > 239: > 240: @ForceInline > 241: public boolean isLoaded(MemorySessionImpl session, > MappedMemoryUtilsProxy mappedUtils, long address, boolean isSync, long size) { This method is called by both the memory segment and byte buffer implementations, so I chose to keep the implementation centralized here, instead of having each client replicate the acquire/release code. ------------- PR Comment: https://git.openjdk.org/jdk/pull/31918#issuecomment-4986798355 PR Review Comment: https://git.openjdk.org/jdk/pull/31918#discussion_r3590232762 PR Review Comment: https://git.openjdk.org/jdk/pull/31918#discussion_r3590238461
