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


Reply via email to