Mercurial > hg > graal-compiler
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 |