comparison src/share/vm/memory/metaspace.cpp @ 7208:eade6b2e4782

8003554: NPG: move Metablock and Metachunk code out of metaspace.cpp Reviewed-by: coleenp
author jmasa
date Thu, 29 Nov 2012 10:09:04 -0800
parents 5fafdef522c6
children c71879335291
comparison
equal deleted inserted replaced
7207:0f80645e9c26 7208:eade6b2e4782
50 50
51 // Parameters for stress mode testing 51 // Parameters for stress mode testing
52 const uint metadata_deallocate_a_lot_block = 10; 52 const uint metadata_deallocate_a_lot_block = 10;
53 const uint metadata_deallocate_a_lock_chunk = 3; 53 const uint metadata_deallocate_a_lock_chunk = 3;
54 size_t const allocation_from_dictionary_limit = 64 * K; 54 size_t const allocation_from_dictionary_limit = 64 * K;
55 const size_t metadata_chunk_initialize = 0xf7f7f7f7;
56 const size_t metadata_deallocate = 0xf5f5f5f5; 55 const size_t metadata_deallocate = 0xf5f5f5f5;
57 56
58 MetaWord* last_allocated = 0; 57 MetaWord* last_allocated = 0;
59 58
60 // Used in declarations in SpaceManager and ChunkManager 59 // Used in declarations in SpaceManager and ChunkManager
90 // Each SpaceManager maintains a 89 // Each SpaceManager maintains a
91 // list of the chunks it is using and the current chunk. The current 90 // list of the chunks it is using and the current chunk. The current
92 // chunk is the chunk from which allocations are done. Space freed in 91 // chunk is the chunk from which allocations are done. Space freed in
93 // a chunk is placed on the free list of blocks (BlockFreelist) and 92 // a chunk is placed on the free list of blocks (BlockFreelist) and
94 // reused from there. 93 // reused from there.
95 //
96 // Future modification
97 //
98 // The Metachunk can conceivable be replaced by the Chunk in
99 // allocation.hpp. Note that the latter Chunk is the space for
100 // allocation (allocations from the chunk are out of the space in
101 // the Chunk after the header for the Chunk) where as Metachunks
102 // point to space in a VirtualSpace. To replace Metachunks with
103 // Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
104 size_t Metablock::_min_block_byte_size = sizeof(Metablock);
105 #ifdef ASSERT
106 size_t Metablock::_overhead =
107 Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord;
108 #else
109 size_t Metablock::_overhead = 0;
110 #endif
111 94
112 // Pointer to list of Metachunks. 95 // Pointer to list of Metachunks.
113 class ChunkList VALUE_OBJ_CLASS_SPEC { 96 class ChunkList VALUE_OBJ_CLASS_SPEC {
114 // List of free chunks 97 // List of free chunks
115 Metachunk* _head; 98 Metachunk* _head;
621 void dump(outputStream* const out) const; 604 void dump(outputStream* const out) const;
622 void print_on(outputStream* st) const; 605 void print_on(outputStream* st) const;
623 void locked_print_chunks_in_use_on(outputStream* st) const; 606 void locked_print_chunks_in_use_on(outputStream* st) const;
624 607
625 void verify(); 608 void verify();
609 void verify_chunk_size(Metachunk* chunk);
626 NOT_PRODUCT(void mangle_freed_chunks();) 610 NOT_PRODUCT(void mangle_freed_chunks();)
627 #ifdef ASSERT 611 #ifdef ASSERT
628 void verify_allocation_total(); 612 void verify_allocation_total();
629 #endif 613 #endif
630 }; 614 };
631 615
632 uint const SpaceManager::_small_chunk_limit = 4; 616 uint const SpaceManager::_small_chunk_limit = 4;
633
634
635 617
636 const char* SpaceManager::_expand_lock_name = 618 const char* SpaceManager::_expand_lock_name =
637 "SpaceManager chunk allocation lock"; 619 "SpaceManager chunk allocation lock";
638 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1; 620 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
639 Mutex* const SpaceManager::_expand_lock = 621 Mutex* const SpaceManager::_expand_lock =
640 new Mutex(SpaceManager::_expand_lock_rank, 622 new Mutex(SpaceManager::_expand_lock_rank,
641 SpaceManager::_expand_lock_name, 623 SpaceManager::_expand_lock_name,
642 Mutex::_allow_vm_block_flag); 624 Mutex::_allow_vm_block_flag);
643
644 size_t Metachunk::_overhead =
645 Chunk::aligned_overhead_size(sizeof(Metachunk)) / BytesPerWord;
646
647 // New blocks returned by the Metaspace are zero initialized.
648 // We should fix the constructors to not assume this instead.
649 Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {
650 if (p == NULL) {
651 return NULL;
652 }
653
654 Metablock* result = (Metablock*) p;
655
656 // Clear the memory
657 Copy::fill_to_aligned_words((HeapWord*)result, word_size);
658 #ifdef ASSERT
659 result->set_word_size(word_size);
660 #endif
661 return result;
662 }
663
664 // Metachunk methods
665
666 Metachunk* Metachunk::initialize(MetaWord* ptr, size_t word_size) {
667 // Set bottom, top, and end. Allow space for the Metachunk itself
668 Metachunk* chunk = (Metachunk*) ptr;
669
670 MetaWord* chunk_bottom = ptr + _overhead;
671 chunk->set_bottom(ptr);
672 chunk->set_top(chunk_bottom);
673 MetaWord* chunk_end = ptr + word_size;
674 assert(chunk_end > chunk_bottom, "Chunk must be too small");
675 chunk->set_end(chunk_end);
676 chunk->set_next(NULL);
677 chunk->set_word_size(word_size);
678 #ifdef ASSERT
679 size_t data_word_size = pointer_delta(chunk_end, chunk_bottom, sizeof(MetaWord));
680 Copy::fill_to_words((HeapWord*) chunk_bottom, data_word_size, metadata_chunk_initialize);
681 #endif
682 return chunk;
683 }
684
685
686 MetaWord* Metachunk::allocate(size_t word_size) {
687 MetaWord* result = NULL;
688 // If available, bump the pointer to allocate.
689 if (free_word_size() >= word_size) {
690 result = _top;
691 _top = _top + word_size;
692 }
693 return result;
694 }
695
696 // _bottom points to the start of the chunk including the overhead.
697 size_t Metachunk::used_word_size() {
698 return pointer_delta(_top, _bottom, sizeof(MetaWord));
699 }
700
701 size_t Metachunk::free_word_size() {
702 return pointer_delta(_end, _top, sizeof(MetaWord));
703 }
704
705 size_t Metachunk::capacity_word_size() {
706 return pointer_delta(_end, _bottom, sizeof(MetaWord));
707 }
708
709 void Metachunk::print_on(outputStream* st) const {
710 st->print_cr("Metachunk:"
711 " bottom " PTR_FORMAT " top " PTR_FORMAT
712 " end " PTR_FORMAT " size " SIZE_FORMAT,
713 bottom(), top(), end(), word_size());
714 }
715
716 #ifndef PRODUCT
717 void Metachunk::mangle() {
718 // Mangle the payload of the chunk and not the links that
719 // maintain list of chunks.
720 HeapWord* start = (HeapWord*)(bottom() + overhead());
721 size_t word_size = capacity_word_size() - overhead();
722 Copy::fill_to_words(start, word_size, metadata_chunk_initialize);
723 }
724 #endif // PRODUCT
725
726 void Metachunk::verify() {
727 #ifdef ASSERT
728 // Cannot walk through the blocks unless the blocks have
729 // headers with sizes.
730 assert(_bottom <= _top &&
731 _top <= _end,
732 "Chunk has been smashed");
733 assert(SpaceManager::is_humongous(_word_size) ||
734 _word_size == SpaceManager::MediumChunk ||
735 _word_size == SpaceManager::SmallChunk,
736 "Chunk size is wrong");
737 #endif
738 return;
739 }
740 625
741 // BlockFreelist methods 626 // BlockFreelist methods
742 627
743 BlockFreelist::BlockFreelist() : _dictionary(NULL) {} 628 BlockFreelist::BlockFreelist() : _dictionary(NULL) {}
744 629
2212 // like of the small chunk. 2097 // like of the small chunk.
2213 for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 2098 for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2214 Metachunk* curr = chunks_in_use(i); 2099 Metachunk* curr = chunks_in_use(i);
2215 while (curr != NULL) { 2100 while (curr != NULL) {
2216 curr->verify(); 2101 curr->verify();
2102 verify_chunk_size(curr);
2217 curr = curr->next(); 2103 curr = curr->next();
2218 } 2104 }
2219 } 2105 }
2220 } 2106 }
2107 }
2108
2109 void SpaceManager::verify_chunk_size(Metachunk* chunk) {
2110 assert(is_humongous(chunk->word_size()) ||
2111 chunk->word_size() == MediumChunk ||
2112 chunk->word_size() == SmallChunk,
2113 "Chunk size is wrong");
2114 return;
2221 } 2115 }
2222 2116
2223 #ifdef ASSERT 2117 #ifdef ASSERT
2224 void SpaceManager::verify_allocation_total() { 2118 void SpaceManager::verify_allocation_total() {
2225 #if 0 2119 #if 0