BUG: SystemABI C_LONG and C_LONGLONG are the same
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed May 20 13:41:09 UTC 2020
On 19/05/2020 15:05, Ty Young wrote:
> I don't think hiding low level Panama details is the way to go about
> things, and I hope that if Panama does add a higher level API, it
> doesn't go the route of trying to directly model C code like "Pointer"
> kinda sorta did.
>
>
> I'd personally like to see something like I did, but I'm both biased
> and realize it's probably unrealistic. The amount of classes that this
> otherwise thin abstraction layer is a bit much for the JDK. In my
> defense, the type specific values and arrays only exist because Java
> doesn't support primitive generics.
>
>
> It would be interesting to get a wider perspective on which approach
> is better. Do people think a smaller higher-level API is better which
> has more "god-like" objects or is a more thinly spread, targeted, and
> lots of classes better? I largely stand by the way I went about it,
> but I'm still personally interested in what others prefer and think.
This is a very good and constructive point. What kind of high-level API
would people expect?
By having spent time looking at what other languages did in this area
(e.g. Kotlin, Swift and the likes), and, by also looking at what more
traditional Java bindings for native libraries do (e.g. LWJGL) - at some
point they all seem to reach out for some kind of pointer-like
abstraction. So I think that _not_ having some kind of higher-level
Pointer abstraction in the long run could be counter-productive.
The problem you raise about lack of support for primitives (and, more
generally, looking forward to Valhalla) inline classes inside generics
(although we have plans for those) remains, IMHO, one of the main
blockers to provide one such abstraction. My personal opinion is that
the old pointer API was not too bad, but it failed because it doesn't go
the full way towards supporting the full spectrum of C types.
That is, at some point, libraries are going to start modelling a "C
int", or a "C unsigned long" as a Java int/long - for primarily three
reasons:
* avoid any cost associated with GC
* take advantage of the fact that Java primitives have 'literals' (e.g. 42L)
* operators are available on primitives - they become methods on classes
(e.g. 2 + 3 vs two.plus(three))
There's of course a _lot_ of overlapping with Valhalla here. My sense is
that Valhalla will allows us to reach that carrier type Nirvana that
Panama so badly needs - you need C unsigned ints? Why not just defining
a new inline class `c_unsigned_int` so that you can then operate on it,
create pointers (e.g. `Pointer<c_unsigned_int>`) and so on and so forth?
If we pull that off, then your Java code will look a lot like the C code
that it came from - you will no longer be using `int` as an
approximation for a richer C carrier (which was the trick the old API
was doing) - you will use the carrier you want, with (almost) the name
you want. IMHO this is much better than just using `int` and maybe
sprinkle a bunch of annotation on the side to say "this int is really XYZ".
As a side-effect, bindings written this way will also be more portable
too - since abstractions such as `c_unsigned_long` and the likes can be
coded in a way so that they take into account platform differences.
Which means the signatures of your methods do not change across platforms.
But an approach such as the one I'm musing here requires a lot of help
from Valhalla to make it real. I did some experiments with some
high-level pointer API built on top of FMA, and while the performance
numbers in some cases are really really good (when C2 can see escape
analysis all the way down), in certain cases they can be 10x off what
the low level FMA is at. And performance is not the only issue - I would
suspect that w/o some form of operator overloading, programming with
`c_unsigned_int` would be considerably fussier than with a plain Java
int, so we also need some of the expressiveness enhancements that will,
at some point, be considered as part of Valhalla.
But, these experiments also were useful in proving another point: that,
at the time of writing, the low level FMA is, by far, the fastest option
available for foreign memory access (albeit low level). Adding
abstractions on top is possible, but they all come with some kind of
hefty price tag attached - so I suspect that developers (especially
framework developers) might want to think twice before adding too much
abstractions on top of the basic memory access.
Hopefully, the evolution of the Java platform will allow us to have our
cake and eat it too - e.g. have plenty of inline (GC-free) carriers
which developer can operate upon as if they were primitives - at which
point we'd no longer have to choose between expressiveness and performances.
Maurizio
More information about the panama-dev
mailing list