src/share/vm/runtime/jniHandles.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File webrev Sdiff src/share/vm/runtime

src/share/vm/runtime/jniHandles.cpp

Print this page




 261 JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread)  {
 262   assert(thread == NULL || thread == Thread::current(), "sanity check");
 263   JNIHandleBlock* block;
 264   // Check the thread-local free list for a block so we don't
 265   // have to acquire a mutex.
 266   if (thread != NULL && thread->free_handle_block() != NULL) {
 267     block = thread->free_handle_block();
 268     thread->set_free_handle_block(block->_next);
 269   }
 270   else {
 271     // locking with safepoint checking introduces a potential deadlock:
 272     // - we would hold JNIHandleBlockFreeList_lock and then Threads_lock
 273     // - another would hold Threads_lock (jni_AttachCurrentThread) and then
 274     //   JNIHandleBlockFreeList_lock (JNIHandleBlock::allocate_block)
 275     MutexLockerEx ml(JNIHandleBlockFreeList_lock,
 276                      Mutex::_no_safepoint_check_flag);
 277     if (_block_free_list == NULL) {
 278       // Allocate new block
 279       block = new JNIHandleBlock();
 280       _blocks_allocated++;
 281       if (TraceJNIHandleAllocation) {
 282         tty->print_cr("JNIHandleBlock " INTPTR_FORMAT " allocated (%d total blocks)",
 283                       p2i(block), _blocks_allocated);
 284       }
 285       if (ZapJNIHandleArea) block->zap();
 286       #ifndef PRODUCT
 287       // Link new block to list of all allocated blocks
 288       block->_block_list_link = _block_list;
 289       _block_list = block;
 290       #endif
 291     } else {
 292       // Get block from free list
 293       block = _block_free_list;
 294       _block_free_list = _block_free_list->_next;
 295     }
 296   }
 297   block->_top  = 0;
 298   block->_next = NULL;
 299   block->_pop_frame_link = NULL;
 300   block->_planned_capacity = block_size_in_oops;
 301   // _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
 302   debug_only(block->_last = NULL);
 303   debug_only(block->_free_list = NULL);
 304   debug_only(block->_allocate_before_rebuild = -1);


 482       if (*handle ==  JNIHandles::deleted_handle()) {
 483         // this handle was cleared out by a delete call, reuse it
 484         *handle = (oop) _free_list;
 485         _free_list = handle;
 486         free++;
 487       }
 488     }
 489     // we should not rebuild free list if there are unused handles at the end
 490     assert(current->_top == block_size_in_oops, "just checking");
 491     blocks++;
 492   }
 493   // Heuristic: if more than half of the handles are free we rebuild next time
 494   // as well, otherwise we append a corresponding number of new blocks before
 495   // attempting a free list rebuild again.
 496   int total = blocks * block_size_in_oops;
 497   int extra = total - 2*free;
 498   if (extra > 0) {
 499     // Not as many free handles as we would like - compute number of new blocks to append
 500     _allocate_before_rebuild = (extra + block_size_in_oops - 1) / block_size_in_oops;
 501   }
 502   if (TraceJNIHandleAllocation) {
 503     tty->print_cr("Rebuild free list JNIHandleBlock " INTPTR_FORMAT " blocks=%d used=%d free=%d add=%d",
 504                   p2i(this), blocks, total-free, free, _allocate_before_rebuild);
 505   }
 506 }
 507 
 508 
 509 bool JNIHandleBlock::contains(jobject handle) const {
 510   return ((jobject)&_handles[0] <= handle && handle<(jobject)&_handles[_top]);
 511 }
 512 
 513 
 514 bool JNIHandleBlock::chain_contains(jobject handle) const {
 515   for (JNIHandleBlock* current = (JNIHandleBlock*) this; current != NULL; current = current->_next) {
 516     if (current->contains(handle)) {
 517       return true;
 518     }
 519   }
 520   return false;
 521 }
 522 
 523 
 524 int JNIHandleBlock::length() const {
 525   int result = 1;




 261 JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread)  {
 262   assert(thread == NULL || thread == Thread::current(), "sanity check");
 263   JNIHandleBlock* block;
 264   // Check the thread-local free list for a block so we don't
 265   // have to acquire a mutex.
 266   if (thread != NULL && thread->free_handle_block() != NULL) {
 267     block = thread->free_handle_block();
 268     thread->set_free_handle_block(block->_next);
 269   }
 270   else {
 271     // locking with safepoint checking introduces a potential deadlock:
 272     // - we would hold JNIHandleBlockFreeList_lock and then Threads_lock
 273     // - another would hold Threads_lock (jni_AttachCurrentThread) and then
 274     //   JNIHandleBlockFreeList_lock (JNIHandleBlock::allocate_block)
 275     MutexLockerEx ml(JNIHandleBlockFreeList_lock,
 276                      Mutex::_no_safepoint_check_flag);
 277     if (_block_free_list == NULL) {
 278       // Allocate new block
 279       block = new JNIHandleBlock();
 280       _blocks_allocated++;




 281       if (ZapJNIHandleArea) block->zap();
 282       #ifndef PRODUCT
 283       // Link new block to list of all allocated blocks
 284       block->_block_list_link = _block_list;
 285       _block_list = block;
 286       #endif
 287     } else {
 288       // Get block from free list
 289       block = _block_free_list;
 290       _block_free_list = _block_free_list->_next;
 291     }
 292   }
 293   block->_top  = 0;
 294   block->_next = NULL;
 295   block->_pop_frame_link = NULL;
 296   block->_planned_capacity = block_size_in_oops;
 297   // _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
 298   debug_only(block->_last = NULL);
 299   debug_only(block->_free_list = NULL);
 300   debug_only(block->_allocate_before_rebuild = -1);


 478       if (*handle ==  JNIHandles::deleted_handle()) {
 479         // this handle was cleared out by a delete call, reuse it
 480         *handle = (oop) _free_list;
 481         _free_list = handle;
 482         free++;
 483       }
 484     }
 485     // we should not rebuild free list if there are unused handles at the end
 486     assert(current->_top == block_size_in_oops, "just checking");
 487     blocks++;
 488   }
 489   // Heuristic: if more than half of the handles are free we rebuild next time
 490   // as well, otherwise we append a corresponding number of new blocks before
 491   // attempting a free list rebuild again.
 492   int total = blocks * block_size_in_oops;
 493   int extra = total - 2*free;
 494   if (extra > 0) {
 495     // Not as many free handles as we would like - compute number of new blocks to append
 496     _allocate_before_rebuild = (extra + block_size_in_oops - 1) / block_size_in_oops;
 497   }




 498 }
 499 
 500 
 501 bool JNIHandleBlock::contains(jobject handle) const {
 502   return ((jobject)&_handles[0] <= handle && handle<(jobject)&_handles[_top]);
 503 }
 504 
 505 
 506 bool JNIHandleBlock::chain_contains(jobject handle) const {
 507   for (JNIHandleBlock* current = (JNIHandleBlock*) this; current != NULL; current = current->_next) {
 508     if (current->contains(handle)) {
 509       return true;
 510     }
 511   }
 512   return false;
 513 }
 514 
 515 
 516 int JNIHandleBlock::length() const {
 517   int result = 1;


src/share/vm/runtime/jniHandles.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File