hotspot/src/share/vm/runtime/jniHandles.cpp
JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(thread == NULL || thread == Thread::current(), "sanity check");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
JNIHandleBlock* block;
{- -------------------------------------------
(1) もし thread local な空き領域から確保できるのであれば, そこから確保する.
---------------------------------------- -}
// Check the thread-local free list for a block so we don't
// have to acquire a mutex.
if (thread != NULL && thread->free_handle_block() != NULL) {
block = thread->free_handle_block();
thread->set_free_handle_block(block->_next);
}
{- -------------------------------------------
(1) もし thread local な空き領域からの確保ができなければ,
以下の確保処理を行う.
(なお, この処理は JNIHandleBlockFreeList_lock で排他して行うが,
ロックする際に safepoint の確認は行わない.
下記のコメントによると, 確認すると dead lock する恐れがあるため, とのこと.)
---------------------------------------- -}
else {
// 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);
{- -------------------------------------------
(1.1) もし JNIHandleBlock::_block_free_list にも空きブロックがなければ,
新しい JNIHandleBlock オブジェクトを new して確保する.
(なお, JNIHandleBlock::_block_free_list は
一度使われた JNIHandleBlock を解放された後もすぐ再利用できるように free list でつないだもの.
(See: JNIHandleBlock::release_block()))
---------------------------------------- -}
if (_block_free_list == NULL) {
// Allocate new block
block = new JNIHandleBlock();
_blocks_allocated++;
{- -------------------------------------------
(1.1.1) (トレース出力)
---------------------------------------- -}
if (TraceJNIHandleAllocation) {
tty->print_cr("JNIHandleBlock " INTPTR_FORMAT " allocated (%d total blocks)",
block, _blocks_allocated);
}
{- -------------------------------------------
(1.1.1) (デバッグ用の処理) (関連する develop オプションが指定されている場合にのみ実行) (See: ZapJNIHandleArea)
(JNIHandleBlock::zap() を呼び出して中身を破壊しておく)
---------------------------------------- -}
if (ZapJNIHandleArea) block->zap();
{- -------------------------------------------
(1.1.1) (デバッグ用の処理) (#ifndef PRODUCT 時にのみ実行)
---------------------------------------- -}
#ifndef PRODUCT
// Link new block to list of all allocated blocks
block->_block_list_link = _block_list;
_block_list = block;
#endif
{- -------------------------------------------
(1.1) もし JNIHandleBlock::_block_free_list に空きブロックがあれば,
そこから JNIHandleBlock を取得.
---------------------------------------- -}
} else {
// Get block from free list
block = _block_free_list;
_block_free_list = _block_free_list->_next;
}
}
{- -------------------------------------------
(1) 確保できた JNIHandleBlock オブジェクトの初期化を行う.
---------------------------------------- -}
block->_top = 0;
block->_next = NULL;
block->_pop_frame_link = NULL;
{- -------------------------------------------
(1) (デバッグ用の処理) (debug_only 時にのみ実行)
確保できた JNIHandleBlock オブジェクトの初期化を行う.
(なお, _last, _free_list, 及び _allocate_before_rebuild フィールドについては
JNIHandleBlock::allocate_handle() メソッド内で初期化している.
See: JNIHandleBlock::allocate_handle())
---------------------------------------- -}
// _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
debug_only(block->_last = NULL);
debug_only(block->_free_list = NULL);
debug_only(block->_allocate_before_rebuild = -1);
{- -------------------------------------------
(1) 結果をリターン.
---------------------------------------- -}
return block;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.