hotspot/src/share/vm/memory/metaspace.cpp
changeset 16996 e699388c6dd8
parent 16439 bccb2fe8a9ce
child 17101 3a82a58d9aa9
equal deleted inserted replaced
16995:cb8097f930a4 16996:e699388c6dd8
   101 // list of the chunks it is using and the current chunk.  The current
   101 // list of the chunks it is using and the current chunk.  The current
   102 // chunk is the chunk from which allocations are done.  Space freed in
   102 // chunk is the chunk from which allocations are done.  Space freed in
   103 // a chunk is placed on the free list of blocks (BlockFreelist) and
   103 // a chunk is placed on the free list of blocks (BlockFreelist) and
   104 // reused from there.
   104 // reused from there.
   105 
   105 
   106 // Pointer to list of Metachunks.
   106 typedef class FreeList<Metachunk> ChunkList;
   107 class ChunkList VALUE_OBJ_CLASS_SPEC {
       
   108   // List of free chunks
       
   109   Metachunk* _head;
       
   110 
       
   111  public:
       
   112   // Constructor
       
   113   ChunkList() : _head(NULL) {}
       
   114 
       
   115   // Accessors
       
   116   Metachunk* head() { return _head; }
       
   117   void set_head(Metachunk* v) { _head = v; }
       
   118 
       
   119   // Link at head of the list
       
   120   void add_at_head(Metachunk* head, Metachunk* tail);
       
   121   void add_at_head(Metachunk* head);
       
   122 
       
   123   size_t sum_list_size();
       
   124   size_t sum_list_count();
       
   125   size_t sum_list_capacity();
       
   126 };
       
   127 
   107 
   128 // Manages the global free lists of chunks.
   108 // Manages the global free lists of chunks.
   129 // Has three lists of free chunks, and a total size and
   109 // Has three lists of free chunks, and a total size and
   130 // count that includes all three
   110 // count that includes all three
   131 
   111 
   182   void chunk_freelist_deallocate(Metachunk* chunk);
   162   void chunk_freelist_deallocate(Metachunk* chunk);
   183 
   163 
   184   // Map a size to a list index assuming that there are lists
   164   // Map a size to a list index assuming that there are lists
   185   // for special, small, medium, and humongous chunks.
   165   // for special, small, medium, and humongous chunks.
   186   static ChunkIndex list_index(size_t size);
   166   static ChunkIndex list_index(size_t size);
       
   167 
       
   168   // Add the simple linked list of chunks to the freelist of chunks
       
   169   // of type index.
       
   170   void return_chunks(ChunkIndex index, Metachunk* chunks);
   187 
   171 
   188   // Total of the space in the free chunks list
   172   // Total of the space in the free chunks list
   189   size_t free_chunks_total();
   173   size_t free_chunks_total();
   190   size_t free_chunks_total_in_bytes();
   174   size_t free_chunks_total_in_bytes();
   191 
   175 
   897                                    _virtual_space_count(0) {
   881                                    _virtual_space_count(0) {
   898   MutexLockerEx cl(SpaceManager::expand_lock(),
   882   MutexLockerEx cl(SpaceManager::expand_lock(),
   899                    Mutex::_no_safepoint_check_flag);
   883                    Mutex::_no_safepoint_check_flag);
   900   bool initialization_succeeded = grow_vs(word_size);
   884   bool initialization_succeeded = grow_vs(word_size);
   901 
   885 
       
   886   _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
       
   887   _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk);
       
   888   _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk);
   902   assert(initialization_succeeded,
   889   assert(initialization_succeeded,
   903     " VirtualSpaceList initialization should not fail");
   890     " VirtualSpaceList initialization should not fail");
   904 }
   891 }
   905 
   892 
   906 VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
   893 VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
   911                                    _virtual_space_count(0) {
   898                                    _virtual_space_count(0) {
   912   MutexLockerEx cl(SpaceManager::expand_lock(),
   899   MutexLockerEx cl(SpaceManager::expand_lock(),
   913                    Mutex::_no_safepoint_check_flag);
   900                    Mutex::_no_safepoint_check_flag);
   914   VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs);
   901   VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs);
   915   bool succeeded = class_entry->initialize();
   902   bool succeeded = class_entry->initialize();
       
   903   _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
       
   904   _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
       
   905   _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
   916   assert(succeeded, " VirtualSpaceList initialization should not fail");
   906   assert(succeeded, " VirtualSpaceList initialization should not fail");
   917   link_vs(class_entry, rs.size()/BytesPerWord);
   907   link_vs(class_entry, rs.size()/BytesPerWord);
   918 }
   908 }
   919 
   909 
   920 // Allocate another meta virtual space and add it to the list.
   910 // Allocate another meta virtual space and add it to the list.
  1378   }
  1368   }
  1379   return false;
  1369   return false;
  1380 }
  1370 }
  1381 #endif
  1371 #endif
  1382 
  1372 
  1383 // ChunkList methods
       
  1384 
       
  1385 size_t ChunkList::sum_list_size() {
       
  1386   size_t result = 0;
       
  1387   Metachunk* cur = head();
       
  1388   while (cur != NULL) {
       
  1389     result += cur->word_size();
       
  1390     cur = cur->next();
       
  1391   }
       
  1392   return result;
       
  1393 }
       
  1394 
       
  1395 size_t ChunkList::sum_list_count() {
       
  1396   size_t result = 0;
       
  1397   Metachunk* cur = head();
       
  1398   while (cur != NULL) {
       
  1399     result++;
       
  1400     cur = cur->next();
       
  1401   }
       
  1402   return result;
       
  1403 }
       
  1404 
       
  1405 size_t ChunkList::sum_list_capacity() {
       
  1406   size_t result = 0;
       
  1407   Metachunk* cur = head();
       
  1408   while (cur != NULL) {
       
  1409     result += cur->capacity_word_size();
       
  1410     cur = cur->next();
       
  1411   }
       
  1412   return result;
       
  1413 }
       
  1414 
       
  1415 void ChunkList::add_at_head(Metachunk* head, Metachunk* tail) {
       
  1416   assert_lock_strong(SpaceManager::expand_lock());
       
  1417   assert(head == tail || tail->next() == NULL,
       
  1418          "Not the tail or the head has already been added to a list");
       
  1419 
       
  1420   if (TraceMetadataChunkAllocation && Verbose) {
       
  1421     gclog_or_tty->print("ChunkList::add_at_head(head, tail): ");
       
  1422     Metachunk* cur = head;
       
  1423     while (cur != NULL) {
       
  1424       gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size());
       
  1425       cur = cur->next();
       
  1426     }
       
  1427     gclog_or_tty->print_cr("");
       
  1428   }
       
  1429 
       
  1430   if (tail != NULL) {
       
  1431     tail->set_next(_head);
       
  1432   }
       
  1433   set_head(head);
       
  1434 }
       
  1435 
       
  1436 void ChunkList::add_at_head(Metachunk* list) {
       
  1437   if (list == NULL) {
       
  1438     // Nothing to add
       
  1439     return;
       
  1440   }
       
  1441   assert_lock_strong(SpaceManager::expand_lock());
       
  1442   Metachunk* head = list;
       
  1443   Metachunk* tail = list;
       
  1444   Metachunk* cur = head->next();
       
  1445   // Search for the tail since it is not passed.
       
  1446   while (cur != NULL) {
       
  1447     tail = cur;
       
  1448     cur = cur->next();
       
  1449   }
       
  1450   add_at_head(head, tail);
       
  1451 }
       
  1452 
       
  1453 // ChunkManager methods
  1373 // ChunkManager methods
  1454 
  1374 
  1455 // Verification of _free_chunks_total and _free_chunks_count does not
  1375 // Verification of _free_chunks_total and _free_chunks_count does not
  1456 // work with the CMS collector because its use of additional locks
  1376 // work with the CMS collector because its use of additional locks
  1457 // complicate the mutex deadlock detection but it can still be useful
  1377 // complicate the mutex deadlock detection but it can still be useful
  1551 
  1471 
  1552     if (list == NULL) {
  1472     if (list == NULL) {
  1553       continue;
  1473       continue;
  1554     }
  1474     }
  1555 
  1475 
  1556     result = result + list->sum_list_capacity();
  1476     result = result + list->count() * list->size();
  1557   }
  1477   }
  1558   result = result + humongous_dictionary()->total_size();
  1478   result = result + humongous_dictionary()->total_size();
  1559   return result;
  1479   return result;
  1560 }
  1480 }
  1561 
  1481 
  1565   for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
  1485   for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
  1566     ChunkList* list = free_chunks(i);
  1486     ChunkList* list = free_chunks(i);
  1567     if (list == NULL) {
  1487     if (list == NULL) {
  1568       continue;
  1488       continue;
  1569     }
  1489     }
  1570     count = count + list->sum_list_count();
  1490     count = count + list->count();
  1571   }
  1491   }
  1572   count = count + humongous_dictionary()->total_free_blocks();
  1492   count = count + humongous_dictionary()->total_free_blocks();
  1573   return count;
  1493   return count;
  1574 }
  1494 }
  1575 
  1495 
  1620     if (chunk == NULL) {
  1540     if (chunk == NULL) {
  1621       return NULL;
  1541       return NULL;
  1622     }
  1542     }
  1623 
  1543 
  1624     // Remove the chunk as the head of the list.
  1544     // Remove the chunk as the head of the list.
  1625     free_list->set_head(chunk->next());
  1545     free_list->remove_chunk(chunk);
  1626 
  1546 
  1627     // Chunk is being removed from the chunks free list.
  1547     // Chunk is being removed from the chunks free list.
  1628     dec_free_chunks_total(chunk->capacity_word_size());
  1548     dec_free_chunks_total(chunk->capacity_word_size());
  1629 
  1549 
  1630     if (TraceMetadataChunkAllocation && Verbose) {
  1550     if (TraceMetadataChunkAllocation && Verbose) {
  1677          "Non-humongous variable sized chunk");
  1597          "Non-humongous variable sized chunk");
  1678   if (TraceMetadataChunkAllocation) {
  1598   if (TraceMetadataChunkAllocation) {
  1679     size_t list_count;
  1599     size_t list_count;
  1680     if (list_index(word_size) < HumongousIndex) {
  1600     if (list_index(word_size) < HumongousIndex) {
  1681       ChunkList* list = find_free_chunks_list(word_size);
  1601       ChunkList* list = find_free_chunks_list(word_size);
  1682       list_count = list->sum_list_count();
  1602       list_count = list->count();
  1683     } else {
  1603     } else {
  1684       list_count = humongous_dictionary()->total_count();
  1604       list_count = humongous_dictionary()->total_count();
  1685     }
  1605     }
  1686     tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
  1606     tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
  1687                PTR_FORMAT "  size " SIZE_FORMAT " count " SIZE_FORMAT " ",
  1607                PTR_FORMAT "  size " SIZE_FORMAT " count " SIZE_FORMAT " ",
  1956   if (TraceMetadataChunkAllocation && Verbose) {
  1876   if (TraceMetadataChunkAllocation && Verbose) {
  1957     gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, this);
  1877     gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, this);
  1958   }
  1878   }
  1959 }
  1879 }
  1960 
  1880 
       
  1881 void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) {
       
  1882   if (chunks == NULL) {
       
  1883     return;
       
  1884   }
       
  1885   ChunkList* list = free_chunks(index);
       
  1886   assert(list->size() == chunks->word_size(), "Mismatch in chunk sizes");
       
  1887   assert_lock_strong(SpaceManager::expand_lock());
       
  1888   Metachunk* cur = chunks;
       
  1889 
       
  1890   // This return chunks one at a time.  If a new
       
  1891   // class List can be created that is a base class
       
  1892   // of FreeList then something like FreeList::prepend()
       
  1893   // can be used in place of this loop
       
  1894   while (cur != NULL) {
       
  1895     // Capture the next link before it is changed
       
  1896     // by the call to return_chunk_at_head();
       
  1897     Metachunk* next = cur->next();
       
  1898     cur->set_is_free(true);
       
  1899     list->return_chunk_at_head(cur);
       
  1900     cur = next;
       
  1901   }
       
  1902 }
       
  1903 
  1961 SpaceManager::~SpaceManager() {
  1904 SpaceManager::~SpaceManager() {
  1962   // This call this->_lock which can't be done while holding expand_lock()
  1905   // This call this->_lock which can't be done while holding expand_lock()
  1963   const size_t in_use_before = sum_capacity_in_chunks_in_use();
  1906   const size_t in_use_before = sum_capacity_in_chunks_in_use();
  1964 
  1907 
  1965   MutexLockerEx fcl(SpaceManager::expand_lock(),
  1908   MutexLockerEx fcl(SpaceManager::expand_lock(),
  1993       gclog_or_tty->print_cr("returned %d %s chunks to freelist",
  1936       gclog_or_tty->print_cr("returned %d %s chunks to freelist",
  1994                              sum_count_in_chunks_in_use(i),
  1937                              sum_count_in_chunks_in_use(i),
  1995                              chunk_size_name(i));
  1938                              chunk_size_name(i));
  1996     }
  1939     }
  1997     Metachunk* chunks = chunks_in_use(i);
  1940     Metachunk* chunks = chunks_in_use(i);
  1998     chunk_manager->free_chunks(i)->add_at_head(chunks);
  1941     chunk_manager->return_chunks(i, chunks);
  1999     set_chunks_in_use(i, NULL);
  1942     set_chunks_in_use(i, NULL);
  2000     if (TraceMetadataChunkAllocation && Verbose) {
  1943     if (TraceMetadataChunkAllocation && Verbose) {
  2001       gclog_or_tty->print_cr("updated freelist count %d %s",
  1944       gclog_or_tty->print_cr("updated freelist count %d %s",
  2002                              chunk_manager->free_chunks(i)->sum_list_count(),
  1945                              chunk_manager->free_chunks(i)->count(),
  2003                              chunk_size_name(i));
  1946                              chunk_size_name(i));
  2004     }
  1947     }
  2005     assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
  1948     assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
  2006   }
  1949   }
  2007 
  1950