[foreign] RFR 8217420: Have UniversalNativeInvoker and UniversalUpcallHandler create (and close) the scopes used by boxing code
John Rose
john.r.rose at oracle.com
Tue Jan 22 00:47:36 UTC 2019
On Jan 21, 2019, at 10:13 AM, Jorn Vernee <jbvernee at xs4all.nl> wrote:
>
> We have 2 options here:
>
> 1.) Go with C style. Struct arguments are valid only during an upcall, and we have to manually copy them if we want to 'leak' them from the scope of the upcall.
> 2.) Go with status quo. Struct doesn't need to be copied manually when saving it outside the scope of the upcall. The copy is defensively done in Windows boxing code instead, and sometimes redundant. Only on Windows (for now), struct arguments to an upcall have to be manually released to avoid a memory leak.
I wouldn't call #1 C style, but rather ABI style. C style allows by-value
passes of structs in all directions, with zero concern for pointer scoping,
because the pointers are kept invisible.
I think #2 is closer to C style, properly understood, but it's not perfect
either if it requires manual deallocation.
So, calling #1 ABI style, we then also have:
3.) Go with C style. Struct arguments (as opposed to pointers to structs)
are passed by value and all appearances in Java exhibit value-like semantics,
which includes no lifetime constraints. The struct is copied onto the Java
heap, defensively, and is preserved there with no writability. If we had
true Valhalla value types, it could be a value object instance, but it should
be at least a value-based class.
There's still a trade-off here, as usual. Putting the struct bit-image
on the Java heap means it is safe to share across threads and across
scopes, and will be GC-ed when no longer in use. That's all good.
The downside is you can only use it for further by-value actions,
such as passing it as an argument later on to a down-call or storing
it bitwise into a container. If you need to pass an address for the
struct data to a C function, that address needs to point to a scoped
off-heap copy of the struct value. Internally, at the ABI level, the
by-value calling sequence will almost certainly need to recopy the
struct into registers or into a stack buffer: But that's what C does
anyway, so that copy doesn't really bear on the decision to store
struct values on-heap or off-heap.
Also, design issues for arguments to up-calls are often paralleled
with returns from down-calls, and it's probably true in this case.
Whatever policy we go with for by-value structs should apply
equally to up-call arguments and down-call returns.
— John
More information about the panama-dev
mailing list