comparison src/share/vm/memory/metaspace.cpp @ 12906:94c0343b1887

8026715: Remove the MetaDataDeallocateALot develop flag Reviewed-by: coleenp, mgerdin
author stefank
date Thu, 17 Oct 2013 08:42:41 +0200
parents bdfbb1fb19ca
children 1d1ea10fe09f a6177f601c64
comparison
equal deleted inserted replaced
12905:28df60a5badf 12906:94c0343b1887
50 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary; 50 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary;
51 51
52 // Set this constant to enable slow integrity checking of the free chunk lists 52 // Set this constant to enable slow integrity checking of the free chunk lists
53 const bool metaspace_slow_verify = false; 53 const bool metaspace_slow_verify = false;
54 54
55 // Parameters for stress mode testing
56 const uint metadata_deallocate_a_lot_block = 10;
57 const uint metadata_deallocate_a_lock_chunk = 3;
58 size_t const allocation_from_dictionary_limit = 4 * K; 55 size_t const allocation_from_dictionary_limit = 4 * K;
59 56
60 MetaWord* last_allocated = 0; 57 MetaWord* last_allocated = 0;
61 58
62 size_t Metaspace::_class_metaspace_size; 59 size_t Metaspace::_class_metaspace_size;
147 _free_chunks[MediumIndex].set_size(medium_size); 144 _free_chunks[MediumIndex].set_size(medium_size);
148 } 145 }
149 146
150 // add or delete (return) a chunk to the global freelist. 147 // add or delete (return) a chunk to the global freelist.
151 Metachunk* chunk_freelist_allocate(size_t word_size); 148 Metachunk* chunk_freelist_allocate(size_t word_size);
152 void chunk_freelist_deallocate(Metachunk* chunk);
153 149
154 // Map a size to a list index assuming that there are lists 150 // Map a size to a list index assuming that there are lists
155 // for special, small, medium, and humongous chunks. 151 // for special, small, medium, and humongous chunks.
156 static ChunkIndex list_index(size_t size); 152 static ChunkIndex list_index(size_t size);
157 153
181 ChunkList* free_chunks(ChunkIndex index); 177 ChunkList* free_chunks(ChunkIndex index);
182 178
183 // Returns the list for the given chunk word size. 179 // Returns the list for the given chunk word size.
184 ChunkList* find_free_chunks_list(size_t word_size); 180 ChunkList* find_free_chunks_list(size_t word_size);
185 181
186 // Add and remove from a list by size. Selects 182 // Remove from a list by size. Selects list based on size of chunk.
187 // list based on size of chunk.
188 void free_chunks_put(Metachunk* chuck);
189 Metachunk* free_chunks_get(size_t chunk_word_size); 183 Metachunk* free_chunks_get(size_t chunk_word_size);
190 184
191 // Debug support 185 // Debug support
192 void verify(); 186 void verify();
193 void slow_verify() { 187 void slow_verify() {
531 }; 525 };
532 }; 526 };
533 527
534 class Metadebug : AllStatic { 528 class Metadebug : AllStatic {
535 // Debugging support for Metaspaces 529 // Debugging support for Metaspaces
536 static int _deallocate_block_a_lot_count;
537 static int _deallocate_chunk_a_lot_count;
538 static int _allocation_fail_alot_count; 530 static int _allocation_fail_alot_count;
539 531
540 public: 532 public:
541 static int deallocate_block_a_lot_count() {
542 return _deallocate_block_a_lot_count;
543 }
544 static void set_deallocate_block_a_lot_count(int v) {
545 _deallocate_block_a_lot_count = v;
546 }
547 static void inc_deallocate_block_a_lot_count() {
548 _deallocate_block_a_lot_count++;
549 }
550 static int deallocate_chunk_a_lot_count() {
551 return _deallocate_chunk_a_lot_count;
552 }
553 static void reset_deallocate_chunk_a_lot_count() {
554 _deallocate_chunk_a_lot_count = 1;
555 }
556 static void inc_deallocate_chunk_a_lot_count() {
557 _deallocate_chunk_a_lot_count++;
558 }
559 533
560 static void init_allocation_fail_alot_count(); 534 static void init_allocation_fail_alot_count();
561 #ifdef ASSERT 535 #ifdef ASSERT
562 static bool test_metadata_failure(); 536 static bool test_metadata_failure();
563 #endif 537 #endif
564
565 static void deallocate_chunk_a_lot(SpaceManager* sm,
566 size_t chunk_word_size);
567 static void deallocate_block_a_lot(SpaceManager* sm,
568 size_t chunk_word_size);
569
570 }; 538 };
571 539
572 int Metadebug::_deallocate_block_a_lot_count = 0;
573 int Metadebug::_deallocate_chunk_a_lot_count = 0;
574 int Metadebug::_allocation_fail_alot_count = 0; 540 int Metadebug::_allocation_fail_alot_count = 0;
575 541
576 // SpaceManager - used by Metaspace to handle allocations 542 // SpaceManager - used by Metaspace to handle allocations
577 class SpaceManager : public CHeapObj<mtClass> { 543 class SpaceManager : public CHeapObj<mtClass> {
578 friend class Metaspace; 544 friend class Metaspace;
1532 } 1498 }
1533 } 1499 }
1534 1500
1535 // Metadebug methods 1501 // Metadebug methods
1536 1502
1537 void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm,
1538 size_t chunk_word_size){
1539 #ifdef ASSERT
1540 VirtualSpaceList* vsl = sm->vs_list();
1541 if (MetaDataDeallocateALot &&
1542 Metadebug::deallocate_chunk_a_lot_count() % MetaDataDeallocateALotInterval == 0 ) {
1543 Metadebug::reset_deallocate_chunk_a_lot_count();
1544 for (uint i = 0; i < metadata_deallocate_a_lock_chunk; i++) {
1545 Metachunk* dummy_chunk = vsl->current_virtual_space()->take_from_committed(chunk_word_size);
1546 if (dummy_chunk == NULL) {
1547 break;
1548 }
1549 sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk);
1550
1551 if (TraceMetadataChunkAllocation && Verbose) {
1552 gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ",
1553 sm->sum_count_in_chunks_in_use());
1554 dummy_chunk->print_on(gclog_or_tty);
1555 gclog_or_tty->print_cr(" Free chunks total %d count %d",
1556 sm->chunk_manager()->free_chunks_total_words(),
1557 sm->chunk_manager()->free_chunks_count());
1558 }
1559 }
1560 } else {
1561 Metadebug::inc_deallocate_chunk_a_lot_count();
1562 }
1563 #endif
1564 }
1565
1566 void Metadebug::deallocate_block_a_lot(SpaceManager* sm,
1567 size_t raw_word_size){
1568 #ifdef ASSERT
1569 if (MetaDataDeallocateALot &&
1570 Metadebug::deallocate_block_a_lot_count() % MetaDataDeallocateALotInterval == 0 ) {
1571 Metadebug::set_deallocate_block_a_lot_count(0);
1572 for (uint i = 0; i < metadata_deallocate_a_lot_block; i++) {
1573 MetaWord* dummy_block = sm->allocate_work(raw_word_size);
1574 if (dummy_block == 0) {
1575 break;
1576 }
1577 sm->deallocate(dummy_block, raw_word_size);
1578 }
1579 } else {
1580 Metadebug::inc_deallocate_block_a_lot_count();
1581 }
1582 #endif
1583 }
1584
1585 void Metadebug::init_allocation_fail_alot_count() { 1503 void Metadebug::init_allocation_fail_alot_count() {
1586 if (MetadataAllocationFailALot) { 1504 if (MetadataAllocationFailALot) {
1587 _allocation_fail_alot_count = 1505 _allocation_fail_alot_count =
1588 1+(long)((double)MetadataAllocationFailALotInterval*os::random()/(max_jint+1.0)); 1506 1+(long)((double)MetadataAllocationFailALotInterval*os::random()/(max_jint+1.0));
1589 } 1507 }
1721 1639
1722 ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) { 1640 ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) {
1723 ChunkIndex index = list_index(word_size); 1641 ChunkIndex index = list_index(word_size);
1724 assert(index < HumongousIndex, "No humongous list"); 1642 assert(index < HumongousIndex, "No humongous list");
1725 return free_chunks(index); 1643 return free_chunks(index);
1726 }
1727
1728 void ChunkManager::free_chunks_put(Metachunk* chunk) {
1729 assert_lock_strong(SpaceManager::expand_lock());
1730 ChunkList* free_list = find_free_chunks_list(chunk->word_size());
1731 chunk->set_next(free_list->head());
1732 free_list->set_head(chunk);
1733 // chunk is being returned to the chunk free list
1734 inc_free_chunks_total(chunk->word_size());
1735 slow_locked_verify();
1736 }
1737
1738 void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) {
1739 // The deallocation of a chunk originates in the freelist
1740 // manangement code for a Metaspace and does not hold the
1741 // lock.
1742 assert(chunk != NULL, "Deallocating NULL");
1743 assert_lock_strong(SpaceManager::expand_lock());
1744 slow_locked_verify();
1745 if (TraceMetadataChunkAllocation) {
1746 gclog_or_tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk "
1747 PTR_FORMAT " size " SIZE_FORMAT,
1748 chunk, chunk->word_size());
1749 }
1750 free_chunks_put(chunk);
1751 } 1644 }
1752 1645
1753 Metachunk* ChunkManager::free_chunks_get(size_t word_size) { 1646 Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
1754 assert_lock_strong(SpaceManager::expand_lock()); 1647 assert_lock_strong(SpaceManager::expand_lock());
1755 1648
2067 1960
2068 // Get another chunk out of the virtual space 1961 // Get another chunk out of the virtual space
2069 size_t grow_chunks_by_words = calc_chunk_size(word_size); 1962 size_t grow_chunks_by_words = calc_chunk_size(word_size);
2070 Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); 1963 Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
2071 1964
2072 if (next != NULL) {
2073 Metadebug::deallocate_chunk_a_lot(this, grow_chunks_by_words);
2074 }
2075
2076 MetaWord* mem = NULL; 1965 MetaWord* mem = NULL;
2077 1966
2078 // If a chunk was available, add it to the in-use chunk list 1967 // If a chunk was available, add it to the in-use chunk list
2079 // and do an allocation from it. 1968 // and do an allocation from it.
2080 if (next != NULL) { 1969 if (next != NULL) {
2415 p = fl->get_block(raw_word_size); 2304 p = fl->get_block(raw_word_size);
2416 } 2305 }
2417 if (p == NULL) { 2306 if (p == NULL) {
2418 p = allocate_work(raw_word_size); 2307 p = allocate_work(raw_word_size);
2419 } 2308 }
2420 Metadebug::deallocate_block_a_lot(this, raw_word_size);
2421 2309
2422 return p; 2310 return p;
2423 } 2311 }
2424 2312
2425 // Returns the address of spaced allocated for "word_size". 2313 // Returns the address of spaced allocated for "word_size".