src/hotspot/share/gc/shared/oopStorage.cpp
changeset 57551 02cffb476ab0
parent 57550 278795ad438a
child 58679 9c3209ff7550
child 59247 56bf71d64d51
equal deleted inserted replaced
57550:278795ad438a 57551:02cffb476ab0
   416   Block* block = block_for_allocation();
   416   Block* block = block_for_allocation();
   417   if (block == NULL) return NULL; // Block allocation failed.
   417   if (block == NULL) return NULL; // Block allocation failed.
   418   assert(!block->is_full(), "invariant");
   418   assert(!block->is_full(), "invariant");
   419   if (block->is_empty()) {
   419   if (block->is_empty()) {
   420     // Transitioning from empty to not empty.
   420     // Transitioning from empty to not empty.
   421     log_debug(oopstorage, blocks)("%s: block not empty " PTR_FORMAT, name(), p2i(block));
   421     log_trace(oopstorage, blocks)("%s: block not empty " PTR_FORMAT, name(), p2i(block));
   422   }
   422   }
   423   oop* result = block->allocate();
   423   oop* result = block->allocate();
   424   assert(result != NULL, "allocation failed");
   424   assert(result != NULL, "allocation failed");
   425   assert(!block->is_empty(), "postcondition");
   425   assert(!block->is_empty(), "postcondition");
   426   Atomic::inc(&_allocation_count); // release updates outside lock.
   426   Atomic::inc(&_allocation_count); // release updates outside lock.
   427   if (block->is_full()) {
   427   if (block->is_full()) {
   428     // Transitioning from not full to full.
   428     // Transitioning from not full to full.
   429     // Remove full blocks from consideration by future allocates.
   429     // Remove full blocks from consideration by future allocates.
   430     log_debug(oopstorage, blocks)("%s: block full " PTR_FORMAT, name(), p2i(block));
   430     log_trace(oopstorage, blocks)("%s: block full " PTR_FORMAT, name(), p2i(block));
   431     _allocation_list.unlink(*block);
   431     _allocation_list.unlink(*block);
   432   }
   432   }
   433   log_trace(oopstorage, ref)("%s: allocated " PTR_FORMAT, name(), p2i(result));
   433   log_trace(oopstorage, ref)("%s: allocated " PTR_FORMAT, name(), p2i(result));
   434   return result;
   434   return result;
   435 }
   435 }
   479       // Trying to add a block failed, but some other thread added to the
   479       // Trying to add a block failed, but some other thread added to the
   480       // list while we'd dropped the lock over the new block allocation.
   480       // list while we'd dropped the lock over the new block allocation.
   481     } else if (!reduce_deferred_updates()) { // Once more before failure.
   481     } else if (!reduce_deferred_updates()) { // Once more before failure.
   482       // Attempt to add a block failed, no other thread added a block,
   482       // Attempt to add a block failed, no other thread added a block,
   483       // and no deferred updated added a block, then allocation failed.
   483       // and no deferred updated added a block, then allocation failed.
   484       log_debug(oopstorage, blocks)("%s: failed block allocation", name());
   484       log_info(oopstorage, blocks)("%s: failed block allocation", name());
   485       return NULL;
   485       return NULL;
   486     }
   486     }
   487   }
   487   }
   488 }
   488 }
   489 
   489 
   571 
   571 
   572 static void log_release_transitions(uintx releasing,
   572 static void log_release_transitions(uintx releasing,
   573                                     uintx old_allocated,
   573                                     uintx old_allocated,
   574                                     const OopStorage* owner,
   574                                     const OopStorage* owner,
   575                                     const void* block) {
   575                                     const void* block) {
   576   Log(oopstorage, blocks) log;
   576   LogTarget(Trace, oopstorage, blocks) lt;
   577   LogStream ls(log.debug());
   577   if (lt.is_enabled()) {
   578   if (is_full_bitmask(old_allocated)) {
   578     LogStream ls(lt);
   579     ls.print_cr("%s: block not full " PTR_FORMAT, owner->name(), p2i(block));
   579     if (is_full_bitmask(old_allocated)) {
   580   }
   580       ls.print_cr("%s: block not full " PTR_FORMAT, owner->name(), p2i(block));
   581   if (releasing == old_allocated) {
   581     }
   582     ls.print_cr("%s: block empty " PTR_FORMAT, owner->name(), p2i(block));
   582     if (releasing == old_allocated) {
       
   583       ls.print_cr("%s: block empty " PTR_FORMAT, owner->name(), p2i(block));
       
   584     }
   583   }
   585   }
   584 }
   586 }
   585 
   587 
   586 void OopStorage::Block::release_entries(uintx releasing, OopStorage* owner) {
   588 void OopStorage::Block::release_entries(uintx releasing, OopStorage* owner) {
   587   assert(releasing != 0, "preconditon");
   589   assert(releasing != 0, "preconditon");
   604   // reduce_deferred_updates will make any needed changes related to this
   606   // reduce_deferred_updates will make any needed changes related to this
   605   // block and _allocation_list.  This deferral avoids _allocation_list
   607   // block and _allocation_list.  This deferral avoids _allocation_list
   606   // updates and the associated locking here.
   608   // updates and the associated locking here.
   607   if ((releasing == old_allocated) || is_full_bitmask(old_allocated)) {
   609   if ((releasing == old_allocated) || is_full_bitmask(old_allocated)) {
   608     // Log transitions.  Both transitions are possible in a single update.
   610     // Log transitions.  Both transitions are possible in a single update.
   609     if (log_is_enabled(Debug, oopstorage, blocks)) {
   611     log_release_transitions(releasing, old_allocated, owner, this);
   610       log_release_transitions(releasing, old_allocated, owner, this);
       
   611     }
       
   612     // Attempt to claim responsibility for adding this block to the deferred
   612     // Attempt to claim responsibility for adding this block to the deferred
   613     // list, by setting the link to non-NULL by self-looping.  If this fails,
   613     // list, by setting the link to non-NULL by self-looping.  If this fails,
   614     // then someone else has made such a claim and the deferred update has not
   614     // then someone else has made such a claim and the deferred update has not
   615     // yet been processed and will include our change, so we don't need to do
   615     // yet been processed and will include our change, so we don't need to do
   616     // anything further.
   616     // anything further.
   629       // some.  And the service thread will drain the entire deferred list
   629       // some.  And the service thread will drain the entire deferred list
   630       // if there are any pending to-empty transitions.
   630       // if there are any pending to-empty transitions.
   631       if (releasing == old_allocated) {
   631       if (releasing == old_allocated) {
   632         owner->record_needs_cleanup();
   632         owner->record_needs_cleanup();
   633       }
   633       }
   634       log_debug(oopstorage, blocks)("%s: deferred update " PTR_FORMAT,
   634       log_trace(oopstorage, blocks)("%s: deferred update " PTR_FORMAT,
   635                                     owner->name(), p2i(this));
   635                                     owner->name(), p2i(this));
   636     }
   636     }
   637   }
   637   }
   638   // Release hold on empty block deletion.
   638   // Release hold on empty block deletion.
   639   Atomic::dec(&_release_refcount);
   639   Atomic::dec(&_release_refcount);
   679   if (is_empty_bitmask(allocated)) {
   679   if (is_empty_bitmask(allocated)) {
   680     _allocation_list.unlink(*block);
   680     _allocation_list.unlink(*block);
   681     _allocation_list.push_back(*block);
   681     _allocation_list.push_back(*block);
   682   }
   682   }
   683 
   683 
   684   log_debug(oopstorage, blocks)("%s: processed deferred update " PTR_FORMAT,
   684   log_trace(oopstorage, blocks)("%s: processed deferred update " PTR_FORMAT,
   685                                 name(), p2i(block));
   685                                 name(), p2i(block));
   686   return true;              // Processed one pending update.
   686   return true;              // Processed one pending update.
   687 }
   687 }
   688 
   688 
   689 inline void check_release_entry(const oop* entry) {
   689 inline void check_release_entry(const oop* entry) {