< prev index next >

src/hotspot/share/memory/metaspace/virtualSpaceList.cpp

Print this page




  72   assert_lock_strong(MetaspaceExpand_lock);
  73   _committed_words = _committed_words - v;
  74 
  75   assert_committed_below_limit();
  76 }
  77 
  78 void VirtualSpaceList::inc_virtual_space_count() {
  79   assert_lock_strong(MetaspaceExpand_lock);
  80   _virtual_space_count++;
  81 }
  82 
  83 void VirtualSpaceList::dec_virtual_space_count() {
  84   assert_lock_strong(MetaspaceExpand_lock);
  85   _virtual_space_count--;
  86 }
  87 
  88 // Walk the list of VirtualSpaceNodes and delete
  89 // nodes with a 0 container_count.  Remove Metachunks in
  90 // the node from their respective freelists.
  91 void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
  92   assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
  93   assert_lock_strong(MetaspaceExpand_lock);
  94   // Don't use a VirtualSpaceListIterator because this
  95   // list is being changed and a straightforward use of an iterator is not safe.
  96   VirtualSpaceNode* purged_vsl = NULL;
  97   VirtualSpaceNode* prev_vsl = virtual_space_list();
  98   VirtualSpaceNode* next_vsl = prev_vsl;
  99   while (next_vsl != NULL) {
 100     VirtualSpaceNode* vsl = next_vsl;
 101     DEBUG_ONLY(vsl->verify_container_count();)
 102     next_vsl = vsl->next();
 103     // Don't free the current virtual space since it will likely
 104     // be needed soon.
 105     if (vsl->container_count() == 0 && vsl != current_virtual_space()) {
 106       log_trace(gc, metaspace, freelist)("Purging VirtualSpaceNode " PTR_FORMAT " (capacity: " SIZE_FORMAT
 107                                          ", used: " SIZE_FORMAT ").", p2i(vsl), vsl->capacity_words_in_vs(), vsl->used_words_in_vs());
 108       DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_vsnodes_purged));
 109       // Unlink it from the list
 110       if (prev_vsl == vsl) {
 111         // This is the case of the current node being the first node.
 112         assert(vsl == virtual_space_list(), "Expected to be the first node");


 125       prev_vsl = vsl;
 126     }
 127   }
 128 #ifdef ASSERT
 129   if (purged_vsl != NULL) {
 130     // List should be stable enough to use an iterator here.
 131     VirtualSpaceListIterator iter(virtual_space_list());
 132     while (iter.repeat()) {
 133       VirtualSpaceNode* vsl = iter.get_next();
 134       assert(vsl != purged_vsl, "Purge of vsl failed");
 135     }
 136   }
 137 #endif
 138 }
 139 
 140 
 141 // This function looks at the mmap regions in the metaspace without locking.
 142 // The chunks are added with store ordering and not deleted except for at
 143 // unloading time during a safepoint.
 144 VirtualSpaceNode* VirtualSpaceList::find_enclosing_space(const void* ptr) {


 145   // List should be stable enough to use an iterator here because removing virtual
 146   // space nodes is only allowed at a safepoint.
 147   VirtualSpaceListIterator iter(virtual_space_list());
 148   while (iter.repeat()) {
 149     VirtualSpaceNode* vsn = iter.get_next();
 150     if (vsn->contains(ptr)) {
 151       return vsn;
 152     }
 153   }
 154   return NULL;
 155 }
 156 
 157 void VirtualSpaceList::retire_current_virtual_space() {
 158   assert_lock_strong(MetaspaceExpand_lock);
 159 
 160   VirtualSpaceNode* vsn = current_virtual_space();
 161 
 162   ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() :
 163                                   Metaspace::chunk_manager_metadata();
 164 




  72   assert_lock_strong(MetaspaceExpand_lock);
  73   _committed_words = _committed_words - v;
  74 
  75   assert_committed_below_limit();
  76 }
  77 
  78 void VirtualSpaceList::inc_virtual_space_count() {
  79   assert_lock_strong(MetaspaceExpand_lock);
  80   _virtual_space_count++;
  81 }
  82 
  83 void VirtualSpaceList::dec_virtual_space_count() {
  84   assert_lock_strong(MetaspaceExpand_lock);
  85   _virtual_space_count--;
  86 }
  87 
  88 // Walk the list of VirtualSpaceNodes and delete
  89 // nodes with a 0 container_count.  Remove Metachunks in
  90 // the node from their respective freelists.
  91 void VirtualSpaceList::purge(ChunkManager* chunk_manager) {

  92   assert_lock_strong(MetaspaceExpand_lock);
  93   // Don't use a VirtualSpaceListIterator because this
  94   // list is being changed and a straightforward use of an iterator is not safe.
  95   VirtualSpaceNode* purged_vsl = NULL;
  96   VirtualSpaceNode* prev_vsl = virtual_space_list();
  97   VirtualSpaceNode* next_vsl = prev_vsl;
  98   while (next_vsl != NULL) {
  99     VirtualSpaceNode* vsl = next_vsl;
 100     DEBUG_ONLY(vsl->verify_container_count();)
 101     next_vsl = vsl->next();
 102     // Don't free the current virtual space since it will likely
 103     // be needed soon.
 104     if (vsl->container_count() == 0 && vsl != current_virtual_space()) {
 105       log_trace(gc, metaspace, freelist)("Purging VirtualSpaceNode " PTR_FORMAT " (capacity: " SIZE_FORMAT
 106                                          ", used: " SIZE_FORMAT ").", p2i(vsl), vsl->capacity_words_in_vs(), vsl->used_words_in_vs());
 107       DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_vsnodes_purged));
 108       // Unlink it from the list
 109       if (prev_vsl == vsl) {
 110         // This is the case of the current node being the first node.
 111         assert(vsl == virtual_space_list(), "Expected to be the first node");


 124       prev_vsl = vsl;
 125     }
 126   }
 127 #ifdef ASSERT
 128   if (purged_vsl != NULL) {
 129     // List should be stable enough to use an iterator here.
 130     VirtualSpaceListIterator iter(virtual_space_list());
 131     while (iter.repeat()) {
 132       VirtualSpaceNode* vsl = iter.get_next();
 133       assert(vsl != purged_vsl, "Purge of vsl failed");
 134     }
 135   }
 136 #endif
 137 }
 138 
 139 
 140 // This function looks at the mmap regions in the metaspace without locking.
 141 // The chunks are added with store ordering and not deleted except for at
 142 // unloading time during a safepoint.
 143 VirtualSpaceNode* VirtualSpaceList::find_enclosing_space(const void* ptr) {
 144   MutexLockerEx cl(MetaspaceExpand_lock,
 145                    Mutex::_no_safepoint_check_flag);
 146   // List should be stable enough to use an iterator here because removing virtual
 147   // space nodes is only allowed at a safepoint.
 148   VirtualSpaceListIterator iter(virtual_space_list());
 149   while (iter.repeat()) {
 150     VirtualSpaceNode* vsn = iter.get_next();
 151     if (vsn->contains(ptr)) {
 152       return vsn;
 153     }
 154   }
 155   return NULL;
 156 }
 157 
 158 void VirtualSpaceList::retire_current_virtual_space() {
 159   assert_lock_strong(MetaspaceExpand_lock);
 160 
 161   VirtualSpaceNode* vsn = current_virtual_space();
 162 
 163   ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() :
 164                                   Metaspace::chunk_manager_metadata();
 165 


< prev index next >