Unification of jni_<platform>.h
Magnus Ihse Bursie
magnus.ihse.bursie at oracle.com
Wed Oct 18 13:10:33 UTC 2017
In the context of JDK-8167078 (Duplicate header files in hotspot and
jdk), I was looking at unifying the platform specific extensions to
jni.h, the jni_md.h files between hotspot and java.base.
The main difference here is that the hotspot jni_* files are divided
into individual files based on cpu, while the java.base versions are
divided according to operating system (which, in turn, implicates
compiler). On a second look, however, it turns out to not be so
problematic -- a hotspot file like jni_x86.h contains basically
... // do windows stuff
... // do posix/macos stuff
and the two blocks match very well what the java.base versions are doing
for the different operating systems.
In fact, the OS (and compiler) division seems more natural, since there
is much redundancy in the hotspot files, and the java.base OS-based
versions are much simpler.
I'm proposing to remove the hotspot CPU-based files and just replace
them with the java.base versions. However, a few differences crept out.
I'd like to discuss them before proceeding.
For jni_aarch64.h: There's a windows (or rather, "not unix") part of the
jni_aarch64.h that I do not believe have ever been used. Nevertheless,
it contains "typedef int jint" rather than "typedef long jint", which
the java.base windows version uses. Since I've never heard of aarch64
building on Windows, I presume this is irrelevant.
For jni_aarch64.h and jni_sparc.h: The unix version will match with the
java.base version as long as _LP64 is defined. This should be just fine,
since we define that when building hotspot/the JDK, and the java.base
version that is exported by the JDK on linux/aarch64 and solaris/sparc
has always required the _LP64 define.
(In fact, the macos and unix versions in java.base only contain trivial
differences. The macos version should probably be removed in favor of a
single unix version.)
For jni_x86.h: There windows part suffers the same problem as for
aarch64, but here it's potentially problematic. The hotspot version uses
"typedef int jint" while the java.base version uses "typedef long jint".
If this *really* were a problem, we would probably have gotten reports
from JNI code unable to work on Windows, so I assume this turns out to
be the same datatype in the end. Don't know if it's due to luck,
compiler flags or by definition.
For jni_s390.h: Here's the most problematic version. The exported
java.base version uses:
typedef long jlong;
typedef long long jlong;
but s390 uses:
typedef long int jlong;
My best assumption here is that we're only really using s390x (the
64-bit version) and that "long int" is functionally equivalent to
"long". Or that jni is broken on s390 and nobody really noticed.
Also, s390 uses a simplified version of the gcc attribute dance used for
JNIEXPORT/JNIIMPORT. I think the s390 version is just not really
updated, and that using the newer in java.base is harmless.
For jni_arm.h: Finally, the jni_arm.h (the 32-bit formerly closed Oracle
port), the JNIEXPORT/JNIIMPORT is different, by defining
__attribute__((externally_visible)). This might have been relevant due
to compile/link time symbol processing for that platform, but
technically it should probably not have been connected to the platform
per se, but rather to the compilation procedure. Since the arm-32
platform is kind of abandoned right now, I propose to modify the
compilation to be more standard, if this is required, rather than
keeping these attributes.
More information about the build-dev