New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8296417: Make memory session a pure lifetime abstraction #750
8296417: Make memory session a pure lifetime abstraction #750
Conversation
👋 Welcome back mcimadamore! A progress list of the required criteria for merging this PR into |
764383b
to
b7010bd
Compare
b7010bd
to
6d5898d
Compare
* Adding new resources to the global session, does nothing: as the session can never become not-alive, there is nothing to track. | ||
* Acquiring and or releasing a memory session similarly does nothing. | ||
*/ | ||
final class GlobalSession extends MemorySessionImpl { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've decided to split this (and implicit sessions) up, for better clarity
* Creates an arena-based allocator used to allocate native segments. The returned allocator features | ||
* the given block size {@code B} and the given arena size {@code A}, and the native segments | ||
* it allocates are associated with the provided memory session. | ||
* Returns a segment allocator which responds to allocation requests by returning consecutive slices |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: newNativeArena
is now gone, and replaced with a more general "slicing allocator". The reason I did this was two-fold: the arena factory seemed to be fairly specific, and not very useful to build upon (slicing allocator greatly improve on that aspect). The second problem is the name: now that we have a toplevel Arena, I think having an arena allocator factory here would be too confusing. I don't think the loss in functionality is significant (newNativeArena can be trivially implemented in terms of a slicing allocator), but if we really need it, we could always add another Arena subclass (e.g. SlicingArena which does more or less what the old allocator did.
Webrevs
|
src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java
Outdated
Show resolved
Hide resolved
src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java
Outdated
Show resolved
Hide resolved
src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
Outdated
Show resolved
Hide resolved
src/java.base/share/classes/java/lang/foreign/MemorySession.java
Outdated
Show resolved
Hide resolved
test/micro/org/openjdk/bench/java/lang/foreign/LoopOverPollutedSegments.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
/** | ||
* {@return the session associated with this arena} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, curly bracers around @return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the inline javadoc return tag?
*/ | ||
static MemorySegment allocateNative(long byteSize, long byteAlignment) { | ||
static MemorySegment allocateNative(long byteSize, long byteAlignment, MemorySession session) { | ||
Objects.requireNonNull(session); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swap checking order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of our tests (TestNulls) rely on nulls being checked first. I'm ok with swapping when there are two null checks (as in allocateNative(MemoryLayout, MemorySession)
).
* exceeds the arena size {@code A}, or the system capacity. Furthermore, the returned allocator is not thread safe. | ||
* Concurrent allocation needs to be guarded with synchronization primitives. | ||
* When the returned allocator cannot satisfy an allocation request, e.g. because a slice of the provided | ||
* segment with the requested size cannot be found, an {@link IndexOutOfBoundsException} is thrown. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type of exception appears a bit strange to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the implementation of this method is based on MemorySegment::asSlice
, I think the exception type is not too bad.
@mcimadamore This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been no new commits pushed to the ➡️ To integrate this PR with the above commit message to the |
Co-authored-by: Jorn Vernee <JornVernee@users.noreply.github.com>
/integrate |
Going to push as commit 2c9ab7c. |
@mcimadamore Pushed as commit 2c9ab7c. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
I think that |
Names can be changed. I agree that That said, I'd like to understand more where the problem is with |
@mcimadamore I think Moreover, in memory contexts, an arena is often used to indicate a contiguous piece of memory that can be sliced out to satisfy requested allocations. As a result, using it for an orthogonal responsibility may be confusing. Thank you very much. |
Personally I think we could use |
But the pure temporal abstraction is MemorySession, not Arena (hence why you need to go from Arena to a session to e.g. map a segment).
Ok, so your angle is: Arena is an allocator with very specific properties. I think that's fair - although Arena is also an allocator - and preserves a main properties or arena allocators - which is that when the arena is closed, all the memory is invalidated at once. It seems like the fact that the arena is contiguous or not under the hood (which is an impl change which we might in fact improve over time) should not be too much of a distraction?
|
My view is that an While I agree with your definition of an arena from the theoretical point of view, practically, an arena allocator is often used to indicate a more specific kind of allocator and the arena is often used to indicate the underlying segment that gets sliced. For example, protobuf C++ API specifies an Arena as: 1
In contrast, in C++ standard, to specify a kind of memory source that "releases the allocated memory only when the resource is destroyed." the standard calls it Thanks a lot. |
|
We are using "Arena" to generally convey "a particular area of activity" related to memory management e.g. the activities of 1) allocation of segments associated with the arena's session; and 2) deallocation of all allocated segments, within the area of the try-with-resources body. |
Some sessions are associated with arenas, some are not (global and implicit). In my mental model, the current session is more of an access control bit on the side of a memory segment, which is consulted prior to a memory access operation. So, IMHO the real issue here is (1) the fact that coming from a world where there's only MemorySession this new shift seems surprising and (2), a toplevel MemorySession abstraction is probably attracting more attention than it should at this point. But these seem things that could be addressed with some naming/javadoc changes. |
Add description
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/panama-foreign pull/750/head:pull/750
$ git checkout pull/750
Update a local copy of the PR:
$ git checkout pull/750
$ git pull https://git.openjdk.org/panama-foreign pull/750/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 750
View PR using the GUI difftool:
$ git pr show -t 750
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/panama-foreign/pull/750.diff