On 2018-03-28 23:53, Martin Buchholz wrote:
I can't find any documentation for what JNIEXPORT and friends actually do.
People including myself have been cargo-culting JNIEXPORT and JNICALL
for decades.
Why aren't they in the JNI spec?
That surprises me. I'm quite certain that javah (or rather, java -h
nowadays) generate header files with JNIEXPORT and JNICALL.
As you can see in the jni.h and jni_md.h files, JNIEXPORT equals
__attribute__((visibility("default"))) for compilers that support it
(gcc and friends), and __declspec(dllexport) for Windows. This means,
that the symbol should be exported. (And it's ignored if you use
mapfiles aka linker scripts.)
As for JNICALL, it's empty on most compilers, but evaluates to __stdcall
on Windows. This defines the calling convention to use. This is required
for JNI calls from Java. (Ask the JVM team why.) While it's not
technically required for calling from one dll to another, it's good
practice to use it all time to be consistent. In any way, it doesn't
hurt us.
---
It's fishy that the attribute externally_visible (which seems very
interesting!) is ARM specific.
#ifdef ARM
#define JNIEXPORT
__attribute__((externally_visible,visibility("default")))
#define JNIIMPORT
__attribute__((externally_visible,visibility("default")))
Yeah, this is broken on so many levels. :-(
The ARM here goes back to the old Oracle proprietary arm32 port. This
used lto, link time optimization, to get an absolutely minimal runtime,
at expense of a extremely long built time. (I think linking libjvm took
like 20 minutes.) But when using lto, you also need to decorate your
functions with the externally_visible attribute. So this was added to
get hotspot to export the proper symbols (since they, too, used the
jni.h file).
So, in short, we should:
1) have used a special, local jni.h file for the proprietary arm port,
and/or
2) added the externally_visible attribute not based on platform, but on
the existence of lto.
At this point in time, we're not building the old 32-bit arm port, and I
doubt anyone does. And even if so, we could probably remove the lto
part, and thus remove this from jni_md.h. If you want, please file a bug.
/Magnus
#else
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#endif