JDK-8231769 : Test tools/javac/tree/MakeTypeTest.java fails with -Xcheck:jni
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8,11,13,14
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-10-02
  • Updated: 2019-10-17
  • Resolved: 2019-10-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 14
14 b19Fixed
Related Reports
Relates :  
Relates :  
Description
It looks like the JNI local handles capacity isn't enough in System.c:

52724:     // Ensure capacity for the array and for a string for each fixed length element
52724:     if ((*env)->EnsureLocalCapacity(env, nstrings + 2) < 0) {
52724:         return NULL;
52724:     }

-Xcheck:jni gives an error:

STDOUT:
WARNING: JNI local refs: 74, exceeds capacity: 73
	at jdk.internal.util.SystemProps$Raw.vmProperties(java.base/Native Method)
	at jdk.internal.util.SystemProps$Raw.cmdProperties(java.base/SystemProps.java:253)
	at jdk.internal.util.SystemProps.initProperties(java.base/SystemProps.java:55)
	at java.lang.System.initPhase1(java.base/System.java:2004)

To reproduce run:
make test TEST=tools/javac/tree/MakeTypeTest.java JTREG="VM_OPTIONS=-Xcheck:jni"
Comments
This seems to affect all versions (checked back to 8). In 11, the same test fails with -Xcheck:jni. There is no such test in 8. Adding affected-versions.
11-10-2019

URL: https://hg.openjdk.java.net/jdk/jdk/rev/7252d89e3a4e User: coleenp Date: 2019-10-11 12:49:53 +0000
11-10-2019

Not sure absolute/relative is the right terminology for this. EnsureLocalCapacity "Ensures that at least a given number of local references can be created in the current thread." so it ensures sufficient space is available irrespective of how many jni refs already exist. So: if ((*env)->EnsureLocalCapacity(env, 1) < 0) is unlikely to have any affect as the initial capacity on method entry is 16 to start with. But see also JDK-8193222. Nesting of calls to ELC were not being handled correctly and the fix implemented was very simplistic. EDIT: Coleen's comment came in while I was composing mine.
10-10-2019

It turns out that there was a jni handle leak in the vm create_from_platform_dependent_str(). The jniCheck capacity amount gives some slop space to account for deleted local handles, but this function wasn't deleting them.
10-10-2019

It appears that the accounting of local capacity is not accurately keeping a cumulative summary of all of the EnsureLocalCapacity calls. During initialization System.c::vmProperties() calls JVM_GetProperties for each of the command line property keys and values. It in turn calls java_lang_String::create_from_platform_dependent_str to create individual strings in the libjava::jni_util.c::newSizedstring8859_1 it calls env-> EnsureLocalCapacity before calling env->NewString. It appears that in HotSpot:jniCheck.cpp: 838; the capacity argument is being treated as a absolute total number of jni refs, not a relative amount so the capacity is not being increased.
10-10-2019