Top


定義場所(file name)

hotspot/src/share/vm/runtime/jniHandles.cpp

名前(function name)

void JNIHandleBlock::release_block(JNIHandleBlock* block, Thread* thread) {

本体部(body)

  {- -------------------------------------------
  (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.