hotspot/src/share/vm/runtime/jniHandles.cpp
void JNIHandleBlock::release_block(JNIHandleBlock* block, Thread* thread) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(thread == NULL || thread == Thread::current(), "sanity check");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
JNIHandleBlock* pop_frame_link = block->pop_frame_link();
{- -------------------------------------------
(1) もし引数で thread が指定されていれば, 開放対象の JNIHandleBlock を
そのスレッドの thread-local free list につなぐ.
(この場合, block を NULL にしてグローバルのフリーリストには追加されないようにしている)
---------------------------------------- -}
// Put returned block at the beginning of the thread-local free list.
// Note that if thread == NULL, we use it as an implicit argument that
// we _don't_ want the block to be kept on the free_handle_block.
// See for instance JavaThread::exit().
if (thread != NULL ) {
if (ZapJNIHandleArea) block->zap();
JNIHandleBlock* freelist = thread->free_handle_block();
block->_pop_frame_link = NULL;
thread->set_free_handle_block(block);
// Add original freelist to end of chain
if ( freelist != NULL ) {
while ( block->_next != NULL ) block = block->_next;
block->_next = freelist;
}
block = NULL;
}
{- -------------------------------------------
(1) 開放対象の JNIHandleBlock をグローバルのフリーリストにつなぐ.
(ただし, 開放対象の JNIHandleBlock が NULL の場合は何もしない)
(なお, つなぐ処理は JNIHandleBlockFreeList_lock を取って排他した状態で行う)
---------------------------------------- -}
if (block != NULL) {
// Return blocks to free list
// locking with safepoint checking introduces a potential deadlock:
// - we would hold JNIHandleBlockFreeList_lock and then Threads_lock
// - another would hold Threads_lock (jni_AttachCurrentThread) and then
// JNIHandleBlockFreeList_lock (JNIHandleBlock::allocate_block)
MutexLockerEx ml(JNIHandleBlockFreeList_lock,
Mutex::_no_safepoint_check_flag);
while (block != NULL) {
if (ZapJNIHandleArea) block->zap();
JNIHandleBlock* next = block->_next;
block->_next = _block_free_list;
_block_free_list = block;
block = next;
}
}
{- -------------------------------------------
(1) もし開放対象の JNIHandleBlock の pop_frame_link が空ではなかった場合は,
念のためにこの関数を再帰呼び出しして処理しておく.
(とはいえ, 普通は空になっているはず.
空になっていないケースは, PopLocalFrame が正しい回数分呼ばれなかった場合のみ)
---------------------------------------- -}
if (pop_frame_link != NULL) {
// As a sanity check we release blocks pointed to by the pop_frame_link.
// This should never happen (only if PopLocalFrame is not called the
// correct number of times).
release_block(pop_frame_link, thread);
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.