RFR (S): 8194309: JNI handle allocation failure not reported correctly

David Holmes david.holmes at oracle.com
Thu Jul 23 08:52:31 UTC 2020

webrev: http://cr.openjdk.java.net/~dholmes/8194309/webrev/
bug: https://bugs.openjdk.java.net/browse/JDK-8194309

The JNI specification states that NewLocalref and NewGloalRef return 
NULL on out-of-memory, whilst NewWeakGlobalRef throws OutofMemoryError. 
But the hotspot implementation will abort on out-of-memory in all cases.

The oop storage code for global and weak-global handles already supports 
taking an AllocFailStrategy, so we simply pass the RETURN_NULL strategy 
through - and in the weak case throw a newly defined OutOfMemoryError 
for "C heap space" (as a corollary for "Java heap space").

For NewLocalRef we pass the strategy through to 
JNIHandleBlock::allocate_block, where we explicitly use "new 
(std::nothrow)" to get a NULL on out-of-memory, so that we can pass it back.

There are three internal calls to NewGlobalRef in jni.cpp that needed a 
NULL check added to support the new behaviour.

In reality we know that if any of these things actually return NULL 
because C-heap is exhausted then chances are we are going to abort soon 
in any case. But to be spec compliant we make the changes.

Note that I deliberately do not change any of the internal 
JNIHandle::make_local calls (contained in the majority of JNI methods) 
to get NULL on out-of-memory. This is because none of those APIs are 
specified in a way that even considers what should happen if an internal 
request to create a local-ref fails - so we can neither return NULL nor 
throw an exception in general. All this fix addresses are the three 
specific JNI entry points themselves.

Also note there is no attempt with this changeset to add NULL checks to 
all the JNI code in the other JDK libraries that uses these API's. 
Interestingly quite a number already include the NULL checks.


There is no practical way to test this for real so I had to use 
fault-injection. A version of the webrev with the fault-injection hooks 
and a test case, is presented here (for the record):


The test is constructed so that only the JNI calls in the test should 
possibly encounter the NULL returns.

Otherwise only sanity testing of tiers 1-3.


More information about the hotspot-runtime-dev mailing list