taming resource scopes
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Jun 2 11:53:50 UTC 2021
On 02/06/2021 12:29, Ty Young wrote:
> Then just returning a primitive address would probably be better then,
> right? Maybe an override could be added that accepts a primitive long
> and does what freeMemory does now while modifying the existing method
> that accepts a MemoryAddress to call close maybe?
If CLinker::allocateMemory returned a plain `long`, it would be more
awkward to interact with it - e.g. to create an unsafe segment out of it.
>
>
> free knows nothing about MemoryAddress or scopes yet the method takes
> in a MemoryAddress and doesn't invalidate the scope by calling close,
> all of which are Panama related and, again, have nothing to do with
> free. It just feels off since MemoryAddress isn't *just* a wrapper
> around a long anymore but has a scope tied to it.
It seems like you are reading too much from the method signature alone.
We could add an extra check to make sure that the address passed in has
the global scope - but it seems like of dubious value, and would likely
restrict usability.
Note that "being attached to a scope" doesn't necessarily means that the
scope is gonna call "free":
```
var scope = ...
var addr = CLinker.allocateMemory(100);
var segment = addr.asSegment(100, scope)
```
Here, `addr` is attached to `scope` - but that doesn't mean an awful
lot, as no cleanup action is defined (and even if a cleanup action was
defined, maybe that cleanup action would just do logging, and not call
"free").
But, stepping back, if you find yourself in a situation where you want
to call CLinker::freeMemory and you don't know if the address comes from
a (safe) segment, or just native code/unsafe allocation, I believe there
should be other (better) ways to solve that problem, rather than having
the unsafe CLinker::freeMemory deal with the mismatch.
These API are useful to create "unsafe" segments - e.g.
```
var scope = ...
var addr = CLinker.allocateMemory(100);
var segment = addr.asSegment(100, () -> CLinker.freeMemory(addr), scope)
```
This gives you a segment backed by malloc which, when `scope` is closed,
will automatically call `free` on the address. So, from the point of
view of clients of this unsafe segment, it's just another segment.
Attempting to dereference will be subject to bound checks and, since
deallocation will occur via ResourceScope::close that will be checked too.
There are of course cases where you don't want to create a segment (this
is the case of pooled allocator, see [1]) - but in those cases the user
is definitively in "sudo" mode (e.g. I know what I'm doing, don't bother
me with checks which, in fact, would only slow things down, since I know
usage is correct).
Maurizio
[1] - https://git.openjdk.java.net/panama-foreign/pull/509
>
>
> I can do this myself with custom bindings, I guess.
More information about the panama-dev
mailing list