40 #include "utilities/copy.hpp" |
40 #include "utilities/copy.hpp" |
41 #include "utilities/debug.hpp" |
41 #include "utilities/debug.hpp" |
42 |
42 |
43 typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary; |
43 typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary; |
44 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary; |
44 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary; |
|
45 // Define this macro to enable slow integrity checking of |
|
46 // the free chunk lists |
|
47 const bool metaspace_slow_verify = false; |
|
48 |
45 |
49 |
46 // Parameters for stress mode testing |
50 // Parameters for stress mode testing |
47 const uint metadata_deallocate_a_lot_block = 10; |
51 const uint metadata_deallocate_a_lot_block = 10; |
48 const uint metadata_deallocate_a_lock_chunk = 3; |
52 const uint metadata_deallocate_a_lock_chunk = 3; |
49 size_t const allocation_from_dictionary_limit = 64 * K; |
53 size_t const allocation_from_dictionary_limit = 64 * K; |
159 |
163 |
160 size_t sum_free_chunks(); |
164 size_t sum_free_chunks(); |
161 size_t sum_free_chunks_count(); |
165 size_t sum_free_chunks_count(); |
162 |
166 |
163 void locked_verify_free_chunks_total(); |
167 void locked_verify_free_chunks_total(); |
|
168 void slow_locked_verify_free_chunks_total() { |
|
169 if (metaspace_slow_verify) { |
|
170 locked_verify_free_chunks_total(); |
|
171 } |
|
172 } |
164 void locked_verify_free_chunks_count(); |
173 void locked_verify_free_chunks_count(); |
|
174 void slow_locked_verify_free_chunks_count() { |
|
175 if (metaspace_slow_verify) { |
|
176 locked_verify_free_chunks_count(); |
|
177 } |
|
178 } |
165 void verify_free_chunks_count(); |
179 void verify_free_chunks_count(); |
166 |
180 |
167 public: |
181 public: |
168 |
182 |
169 ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} |
183 ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} |
199 void free_chunks_put(Metachunk* chuck); |
213 void free_chunks_put(Metachunk* chuck); |
200 Metachunk* free_chunks_get(size_t chunk_word_size); |
214 Metachunk* free_chunks_get(size_t chunk_word_size); |
201 |
215 |
202 // Debug support |
216 // Debug support |
203 void verify(); |
217 void verify(); |
|
218 void slow_verify() { |
|
219 if (metaspace_slow_verify) { |
|
220 verify(); |
|
221 } |
|
222 } |
204 void locked_verify(); |
223 void locked_verify(); |
|
224 void slow_locked_verify() { |
|
225 if (metaspace_slow_verify) { |
|
226 locked_verify(); |
|
227 } |
|
228 } |
205 void verify_free_chunks_total(); |
229 void verify_free_chunks_total(); |
206 |
230 |
207 void locked_print_free_chunks(outputStream* st); |
231 void locked_print_free_chunks(outputStream* st); |
208 void locked_print_sum_free_chunks(outputStream* st); |
232 void locked_print_sum_free_chunks(outputStream* st); |
209 |
233 |
1505 size_t ChunkManager::free_chunks_total() { |
1529 size_t ChunkManager::free_chunks_total() { |
1506 #ifdef ASSERT |
1530 #ifdef ASSERT |
1507 if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) { |
1531 if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) { |
1508 MutexLockerEx cl(SpaceManager::expand_lock(), |
1532 MutexLockerEx cl(SpaceManager::expand_lock(), |
1509 Mutex::_no_safepoint_check_flag); |
1533 Mutex::_no_safepoint_check_flag); |
1510 locked_verify_free_chunks_total(); |
1534 slow_locked_verify_free_chunks_total(); |
1511 } |
1535 } |
1512 #endif |
1536 #endif |
1513 return _free_chunks_total; |
1537 return _free_chunks_total; |
1514 } |
1538 } |
1515 |
1539 |
1522 if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) { |
1546 if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) { |
1523 MutexLockerEx cl(SpaceManager::expand_lock(), |
1547 MutexLockerEx cl(SpaceManager::expand_lock(), |
1524 Mutex::_no_safepoint_check_flag); |
1548 Mutex::_no_safepoint_check_flag); |
1525 // This lock is only needed in debug because the verification |
1549 // This lock is only needed in debug because the verification |
1526 // of the _free_chunks_totals walks the list of free chunks |
1550 // of the _free_chunks_totals walks the list of free chunks |
1527 locked_verify_free_chunks_count(); |
1551 slow_locked_verify_free_chunks_count(); |
1528 } |
1552 } |
1529 #endif |
1553 #endif |
1530 return _free_chunks_count; |
1554 return _free_chunks_count; |
1531 } |
1555 } |
1532 |
1556 |
1533 void ChunkManager::locked_verify_free_chunks_total() { |
1557 void ChunkManager::locked_verify_free_chunks_total() { |
1534 assert_lock_strong(SpaceManager::expand_lock()); |
1558 assert_lock_strong(SpaceManager::expand_lock()); |
1535 assert(sum_free_chunks() == _free_chunks_total, |
1559 assert(sum_free_chunks() == _free_chunks_total, |
1559 locked_verify_free_chunks_count(); |
1583 locked_verify_free_chunks_count(); |
1560 #endif |
1584 #endif |
1561 } |
1585 } |
1562 |
1586 |
1563 void ChunkManager::verify() { |
1587 void ChunkManager::verify() { |
1564 #ifdef ASSERT |
1588 MutexLockerEx cl(SpaceManager::expand_lock(), |
1565 if (!UseConcMarkSweepGC) { |
1589 Mutex::_no_safepoint_check_flag); |
1566 MutexLockerEx cl(SpaceManager::expand_lock(), |
1590 locked_verify(); |
1567 Mutex::_no_safepoint_check_flag); |
|
1568 locked_verify_free_chunks_total(); |
|
1569 locked_verify_free_chunks_count(); |
|
1570 } |
|
1571 #endif |
|
1572 } |
1591 } |
1573 |
1592 |
1574 void ChunkManager::locked_verify() { |
1593 void ChunkManager::locked_verify() { |
1575 locked_verify_free_chunks_count(); |
1594 locked_verify_free_chunks_count(); |
1576 locked_verify_free_chunks_total(); |
1595 locked_verify_free_chunks_total(); |
1640 ChunkList* free_list = find_free_chunks_list(chunk->word_size()); |
1659 ChunkList* free_list = find_free_chunks_list(chunk->word_size()); |
1641 chunk->set_next(free_list->head()); |
1660 chunk->set_next(free_list->head()); |
1642 free_list->set_head(chunk); |
1661 free_list->set_head(chunk); |
1643 // chunk is being returned to the chunk free list |
1662 // chunk is being returned to the chunk free list |
1644 inc_free_chunks_total(chunk->capacity_word_size()); |
1663 inc_free_chunks_total(chunk->capacity_word_size()); |
1645 locked_verify(); |
1664 slow_locked_verify(); |
1646 } |
1665 } |
1647 |
1666 |
1648 void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { |
1667 void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { |
1649 // The deallocation of a chunk originates in the freelist |
1668 // The deallocation of a chunk originates in the freelist |
1650 // manangement code for a Metaspace and does not hold the |
1669 // manangement code for a Metaspace and does not hold the |
1651 // lock. |
1670 // lock. |
1652 assert(chunk != NULL, "Deallocating NULL"); |
1671 assert(chunk != NULL, "Deallocating NULL"); |
1653 // MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); |
1672 assert_lock_strong(SpaceManager::expand_lock()); |
1654 locked_verify(); |
1673 slow_locked_verify(); |
1655 if (TraceMetadataChunkAllocation) { |
1674 if (TraceMetadataChunkAllocation) { |
1656 tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " |
1675 tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " |
1657 PTR_FORMAT " size " SIZE_FORMAT, |
1676 PTR_FORMAT " size " SIZE_FORMAT, |
1658 chunk, chunk->word_size()); |
1677 chunk, chunk->word_size()); |
1659 } |
1678 } |
1661 } |
1680 } |
1662 |
1681 |
1663 Metachunk* ChunkManager::free_chunks_get(size_t word_size) { |
1682 Metachunk* ChunkManager::free_chunks_get(size_t word_size) { |
1664 assert_lock_strong(SpaceManager::expand_lock()); |
1683 assert_lock_strong(SpaceManager::expand_lock()); |
1665 |
1684 |
1666 locked_verify(); |
1685 slow_locked_verify(); |
1667 |
1686 |
1668 Metachunk* chunk = NULL; |
1687 Metachunk* chunk = NULL; |
1669 if (!SpaceManager::is_humongous(word_size)) { |
1688 if (!SpaceManager::is_humongous(word_size)) { |
1670 ChunkList* free_list = find_free_chunks_list(word_size); |
1689 ChunkList* free_list = find_free_chunks_list(word_size); |
1671 assert(free_list != NULL, "Sanity check"); |
1690 assert(free_list != NULL, "Sanity check"); |
1706 #ifdef ASSERT |
1725 #ifdef ASSERT |
1707 chunk->set_is_free(false); |
1726 chunk->set_is_free(false); |
1708 #endif |
1727 #endif |
1709 } |
1728 } |
1710 } |
1729 } |
1711 locked_verify(); |
1730 slow_locked_verify(); |
1712 return chunk; |
1731 return chunk; |
1713 } |
1732 } |
1714 |
1733 |
1715 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { |
1734 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { |
1716 assert_lock_strong(SpaceManager::expand_lock()); |
1735 assert_lock_strong(SpaceManager::expand_lock()); |
1717 locked_verify(); |
1736 slow_locked_verify(); |
1718 |
1737 |
1719 // Take from the beginning of the list |
1738 // Take from the beginning of the list |
1720 Metachunk* chunk = free_chunks_get(word_size); |
1739 Metachunk* chunk = free_chunks_get(word_size); |
1721 if (chunk == NULL) { |
1740 if (chunk == NULL) { |
1722 return NULL; |
1741 return NULL; |
1957 MutexLockerEx fcl(SpaceManager::expand_lock(), |
1976 MutexLockerEx fcl(SpaceManager::expand_lock(), |
1958 Mutex::_no_safepoint_check_flag); |
1977 Mutex::_no_safepoint_check_flag); |
1959 |
1978 |
1960 ChunkManager* chunk_manager = vs_list()->chunk_manager(); |
1979 ChunkManager* chunk_manager = vs_list()->chunk_manager(); |
1961 |
1980 |
1962 chunk_manager->locked_verify(); |
1981 chunk_manager->slow_locked_verify(); |
1963 |
1982 |
1964 if (TraceMetadataChunkAllocation && Verbose) { |
1983 if (TraceMetadataChunkAllocation && Verbose) { |
1965 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); |
1984 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); |
1966 locked_print_chunks_in_use_on(gclog_or_tty); |
1985 locked_print_chunks_in_use_on(gclog_or_tty); |
1967 } |
1986 } |
2013 Metachunk* next_humongous_chunks = humongous_chunks->next(); |
2032 Metachunk* next_humongous_chunks = humongous_chunks->next(); |
2014 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); |
2033 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); |
2015 humongous_chunks = next_humongous_chunks; |
2034 humongous_chunks = next_humongous_chunks; |
2016 } |
2035 } |
2017 set_chunks_in_use(HumongousIndex, NULL); |
2036 set_chunks_in_use(HumongousIndex, NULL); |
2018 chunk_manager->locked_verify(); |
2037 chunk_manager->slow_locked_verify(); |
2019 } |
2038 } |
2020 |
2039 |
2021 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { |
2040 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { |
2022 assert_lock_strong(_lock); |
2041 assert_lock_strong(_lock); |
2023 size_t min_size = TreeChunk<Metablock, FreeList>::min_size(); |
2042 size_t min_size = TreeChunk<Metablock, FreeList>::min_size(); |
2328 |
2347 |
2329 size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { |
2348 size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { |
2330 ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? |
2349 ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? |
2331 Metaspace::class_space_list()->chunk_manager() : |
2350 Metaspace::class_space_list()->chunk_manager() : |
2332 Metaspace::space_list()->chunk_manager(); |
2351 Metaspace::space_list()->chunk_manager(); |
2333 |
2352 chunk->slow_verify(); |
2334 chunk->verify_free_chunks_total(); |
|
2335 return chunk->free_chunks_total(); |
2353 return chunk->free_chunks_total(); |
2336 } |
2354 } |
2337 |
2355 |
2338 size_t MetaspaceAux::free_chunks_total_in_bytes(Metaspace::MetadataType mdtype) { |
2356 size_t MetaspaceAux::free_chunks_total_in_bytes(Metaspace::MetadataType mdtype) { |
2339 return free_chunks_total(mdtype) * BytesPerWord; |
2357 return free_chunks_total(mdtype) * BytesPerWord; |
2433 out->print("data space: "); print_on(out, Metaspace::NonClassType); |
2451 out->print("data space: "); print_on(out, Metaspace::NonClassType); |
2434 out->print("class space: "); print_on(out, Metaspace::ClassType); |
2452 out->print("class space: "); print_on(out, Metaspace::ClassType); |
2435 print_waste(out); |
2453 print_waste(out); |
2436 } |
2454 } |
2437 |
2455 |
|
2456 void MetaspaceAux::verify_free_chunks() { |
|
2457 Metaspace::space_list()->chunk_manager()->verify(); |
|
2458 Metaspace::class_space_list()->chunk_manager()->verify(); |
|
2459 } |
|
2460 |
2438 // Metaspace methods |
2461 // Metaspace methods |
2439 |
2462 |
2440 size_t Metaspace::_first_chunk_word_size = 0; |
2463 size_t Metaspace::_first_chunk_word_size = 0; |
2441 |
2464 |
2442 Metaspace::Metaspace(Mutex* lock, size_t word_size) { |
2465 Metaspace::Metaspace(Mutex* lock, size_t word_size) { |