[foreign-jextract] Closing sliced segment closes original segment

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Aug 4 14:24:29 UTC 2020


On 04/08/2020 15:01, Filip Krakowski wrote:
> I don't know if this makes sense, but I would expect MemorySegments to 
> behave like (direct) ByteBuffers (slices) in this context, since the 
> slice's memory is not released automatically (using a Cleaner) after 
> the slice gets garbage collected. Is there a specific reason as to why 
> child segments close their parent segments? If I got it right, the 
> client would need to check if the segment has the CLOSE access mode 
> set to decide if it may close the segment or not. 

In the byte buffer API, every buffer is managed with a cleaner. A slice 
is a segment which points to the original buffer, hence keeping it 
"alive". The memory access API supports deterministic deallocation, so 
we have to answer a question that the bytebuffer API doesn't have: what 
should happen when a segment slice is closed? There are three possible 
answers:

1) close the original segment
2) do nothing
3) throw

Now, the general sense, when writing the API, was that clients wanted 
either (1) or (2,3). That is, there are cases where you really want the 
slice to act like the real segment, and closing the slice should close 
the whole thing. This is the case where a segment is created, and maybe, 
for alignment purposes, a slice of it is taken, and then worked on by a 
client.

But there are also other cases in which the slices are never really 
meant to be closed, because the slices are portions of a bigger memory 
region that is handled somewhere else. In this case clients want either 
(2) or (3), but never (1), as they do _not_ want the original segment to 
be closed. We preferred (3) over (2) because the API is in general 
pretty aggressive in trying to enforce well-formedness of segments 
invariants - that is, if a segment is non-closeable and you try to close 
it, we like to report an exception, rather than doing nothing.

An alternative is of course possible, where calling asSlice creates a 
new segment with its own independent scope, whose cleanup action does 
nothing. But note that this scope is not really 100% independent: if the 
main segment is closed, then the slice segment should be reported as 
closed as well. This is tricky to get right, and in general seems to 
suggest that a parent segment and all its slices share the _same_ 
temporal bounds: if the parent segment is closed, then all the slices 
derived from it should be considered closed too. If you keep pulling on 
this string, then it follows that closing a slice also results in 
closing the parent segment (since both share the same temporal bounds) - 
and the only thing a client can do to protect against this is to remove 
the CLOSED access mode on the slice. Also, having an API where slicing 
would result in a new stateful scope being created would prevent any 
possibility to implement slices with inline types when Valhalla will 
land. All this seemed to push towards a model where slices are stateless 
entities which share the temporal bounds with some parent segment.

Maurizio




More information about the panama-dev mailing list