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