comparison src/share/vm/memory/metaspace.cpp @ 6885:685df3c6f84b

7045397: NPG: Add freelists to class loader arenas. Reviewed-by: coleenp, stefank, jprovino, ohair
author jmasa
date Tue, 18 Sep 2012 23:35:42 -0700
parents 5baec2e69518
children 6bc207d87e5d
comparison
equal deleted inserted replaced
6877:d0e7716b179e 6885:685df3c6f84b
22 * 22 *
23 */ 23 */
24 #include "precompiled.hpp" 24 #include "precompiled.hpp"
25 #include "gc_interface/collectedHeap.hpp" 25 #include "gc_interface/collectedHeap.hpp"
26 #include "memory/binaryTreeDictionary.hpp" 26 #include "memory/binaryTreeDictionary.hpp"
27 #include "memory/freeList.hpp"
27 #include "memory/collectorPolicy.hpp" 28 #include "memory/collectorPolicy.hpp"
28 #include "memory/filemap.hpp" 29 #include "memory/filemap.hpp"
29 #include "memory/freeList.hpp" 30 #include "memory/freeList.hpp"
31 #include "memory/metablock.hpp"
32 #include "memory/metachunk.hpp"
30 #include "memory/metaspace.hpp" 33 #include "memory/metaspace.hpp"
31 #include "memory/metaspaceShared.hpp" 34 #include "memory/metaspaceShared.hpp"
32 #include "memory/resourceArea.hpp" 35 #include "memory/resourceArea.hpp"
33 #include "memory/universe.hpp" 36 #include "memory/universe.hpp"
34 #include "runtime/globals.hpp" 37 #include "runtime/globals.hpp"
35 #include "runtime/mutex.hpp" 38 #include "runtime/mutex.hpp"
36 #include "services/memTracker.hpp" 39 #include "services/memTracker.hpp"
37 #include "utilities/copy.hpp" 40 #include "utilities/copy.hpp"
38 #include "utilities/debug.hpp" 41 #include "utilities/debug.hpp"
39 42
40 // Define this macro to deallocate Metablock. If not defined, 43 typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary;
41 // blocks are not yet deallocated and are only mangled. 44 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary;
42 #undef DEALLOCATE_BLOCKS
43
44 // Easily recognizable patterns
45 // These patterns can be the same in 32bit or 64bit since
46 // they only have to be easily recognizable.
47 const void* metaspace_allocation_leader = (void*) 0X11111111;
48 const void* metaspace_allocation_trailer = (void*) 0X77777777;
49 45
50 // Parameters for stress mode testing 46 // Parameters for stress mode testing
51 const uint metadata_deallocate_a_lot_block = 10; 47 const uint metadata_deallocate_a_lot_block = 10;
52 const uint metadata_deallocate_a_lock_chunk = 3; 48 const uint metadata_deallocate_a_lock_chunk = 3;
53 size_t const allocation_from_dictionary_limit = 64 * K; 49 size_t const allocation_from_dictionary_limit = 64 * K;
54 const size_t metadata_chunk_initialize = 0xf7f7f7f7; 50 const size_t metadata_chunk_initialize = 0xf7f7f7f7;
55 const size_t metadata_deallocate = 0xf5f5f5f5; 51 const size_t metadata_deallocate = 0xf5f5f5f5;
56 const size_t metadata_space_manager_allocate = 0xf3f3f3f3;
57 52
58 MetaWord* last_allocated = 0; 53 MetaWord* last_allocated = 0;
59 54
60 // Used in declarations in SpaceManager and ChunkManager 55 // Used in declarations in SpaceManager and ChunkManager
61 enum ChunkIndex { 56 enum ChunkIndex {
62 SmallIndex = 0, 57 SmallIndex = 0,
63 MediumIndex = 1, 58 MediumIndex = 1,
64 HumongousIndex = 2, 59 HumongousIndex = 2,
65 NumberOfFreeLists = 3 60 NumberOfFreeLists = 2,
61 NumberOfInUseLists = 3
66 }; 62 };
67 63
68 static ChunkIndex next_chunk_index(ChunkIndex i) { 64 static ChunkIndex next_chunk_index(ChunkIndex i) {
69 assert(i < NumberOfFreeLists, "Out of bound"); 65 assert(i < NumberOfInUseLists, "Out of bound");
70 return (ChunkIndex) (i+1); 66 return (ChunkIndex) (i+1);
71 } 67 }
72 68
73 // Originally _capacity_until_GC was set to MetaspaceSize here but 69 // Originally _capacity_until_GC was set to MetaspaceSize here but
74 // the default MetaspaceSize before argument processing was being 70 // the default MetaspaceSize before argument processing was being
98 // allocation.hpp. Note that the latter Chunk is the space for 94 // allocation.hpp. Note that the latter Chunk is the space for
99 // allocation (allocations from the chunk are out of the space in 95 // allocation (allocations from the chunk are out of the space in
100 // the Chunk after the header for the Chunk) where as Metachunks 96 // the Chunk after the header for the Chunk) where as Metachunks
101 // point to space in a VirtualSpace. To replace Metachunks with 97 // point to space in a VirtualSpace. To replace Metachunks with
102 // Chunks, change Chunks so that they can be allocated out of a VirtualSpace. 98 // Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
103 // 99 size_t Metablock::_min_block_byte_size = sizeof(Metablock);
104
105 // Metablock are the unit of allocation from a Chunk. It contains
106 // the size of the requested allocation in a debug build.
107 // Also in a debug build it has a marker before and after the
108 // body of the block. The address of the body is the address returned
109 // by the allocation.
110 //
111 // Layout in a debug build. In a product build only the body is present.
112 //
113 // +-----------+-----------+------------+ +-----------+
114 // | word size | leader | body | ... | trailer |
115 // +-----------+-----------+------------+ +-----------+
116 //
117 // A Metablock may be reused by its SpaceManager but are never moved between
118 // SpaceManagers. There is no explicit link to the Metachunk
119 // from which it was allocated. Metablock are not deallocated, rather
120 // the Metachunk it is a part of will be deallocated when it's
121 // associated class loader is collected.
122 //
123 // When the word size of a block is passed in to the deallocation
124 // call the word size no longer needs to be part of a Metablock.
125
126 class Metablock {
127 friend class VMStructs;
128 private:
129 // Used to align the allocation (see below) and for debugging.
130 #ifdef ASSERT 100 #ifdef ASSERT
131 struct { 101 size_t Metablock::_overhead =
132 size_t _word_size; 102 Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord;
133 void* _leader; 103 #else
134 } _header; 104 size_t Metablock::_overhead = 0;
135 void* _data[1];
136 #endif 105 #endif
137 static size_t _overhead;
138
139 #ifdef ASSERT
140 void set_word_size(size_t v) { _header._word_size = v; }
141 void* leader() { return _header._leader; }
142 void* trailer() {
143 jlong index = (jlong) _header._word_size - sizeof(_header)/BytesPerWord - 1;
144 assert(index > 0, err_msg("Bad indexling of trailer %d", index));
145 void** ptr = &_data[index];
146 return *ptr;
147 }
148 void set_leader(void* v) { _header._leader = v; }
149 void set_trailer(void* v) {
150 void** ptr = &_data[_header._word_size - sizeof(_header)/BytesPerWord - 1];
151 *ptr = v;
152 }
153 public:
154 size_t word_size() { return _header._word_size; }
155 #endif
156 public:
157
158 static Metablock* initialize(MetaWord* p, size_t word_size);
159
160 // This places the body of the block at a 2 word boundary
161 // because every block starts on a 2 word boundary. Work out
162 // how to make the body on a 2 word boundary if the block
163 // starts on a arbitrary boundary. JJJ
164
165 #ifdef ASSERT
166 MetaWord* data() { return (MetaWord*) &_data[0]; }
167 #else
168 MetaWord* data() { return (MetaWord*) this; }
169 #endif
170 static Metablock* metablock_from_data(MetaWord* p) {
171 #ifdef ASSERT
172 size_t word_offset = offset_of(Metablock, _data)/BytesPerWord;
173 Metablock* result = (Metablock*) (p - word_offset);
174 return result;
175 #else
176 return (Metablock*) p;
177 #endif
178 }
179
180 static size_t overhead() { return _overhead; }
181 void verify();
182 };
183
184 // Metachunk - Quantum of allocation from a Virtualspace
185 // Metachunks are reused (when freed are put on a global freelist) and
186 // have no permanent association to a SpaceManager.
187
188 // +--------------+ <- end
189 // | | --+ ---+
190 // | | | free |
191 // | | | |
192 // | | | | capacity
193 // | | | |
194 // | | <- top --+ |
195 // | | ---+ |
196 // | | | used |
197 // | | | |
198 // | | | |
199 // +--------------+ <- bottom ---+ ---+
200
201 class Metachunk VALUE_OBJ_CLASS_SPEC {
202 // link to support lists of chunks
203 Metachunk* _next;
204
205 MetaWord* _bottom;
206 MetaWord* _end;
207 MetaWord* _top;
208 size_t _word_size;
209
210 // Metachunks are allocated out of a MetadataVirtualSpace and
211 // and use some of its space to describe itself (plus alignment
212 // considerations). Metadata is allocated in the rest of the chunk.
213 // This size is the overhead of maintaining the Metachunk within
214 // the space.
215 static size_t _overhead;
216
217 void set_bottom(MetaWord* v) { _bottom = v; }
218 void set_end(MetaWord* v) { _end = v; }
219 void set_top(MetaWord* v) { _top = v; }
220 void set_word_size(size_t v) { _word_size = v; }
221 public:
222
223 // Used to add a Metachunk to a list of Metachunks
224 void set_next(Metachunk* v) { _next = v; assert(v != this, "Boom");}
225
226 Metablock* allocate(size_t word_size);
227 static Metachunk* initialize(MetaWord* ptr, size_t word_size);
228
229 // Accessors
230 Metachunk* next() const { return _next; }
231 MetaWord* bottom() const { return _bottom; }
232 MetaWord* end() const { return _end; }
233 MetaWord* top() const { return _top; }
234 size_t word_size() const { return _word_size; }
235 static size_t overhead() { return _overhead; }
236
237 // Reset top to bottom so chunk can be reused.
238 void reset_empty() { _top = (_bottom + _overhead); }
239 bool is_empty() { return _top == (_bottom + _overhead); }
240
241 // used (has been allocated)
242 // free (available for future allocations)
243 // capacity (total size of chunk)
244 size_t used_word_size();
245 size_t free_word_size();
246 size_t capacity_word_size();
247
248 #ifdef ASSERT
249 void mangle() {
250 // Mangle the payload of the chunk and not the links that
251 // maintain list of chunks.
252 HeapWord* start = (HeapWord*)(bottom() + overhead());
253 size_t word_size = capacity_word_size() - overhead();
254 Copy::fill_to_words(start, word_size, metadata_chunk_initialize);
255 }
256 #endif // ASSERT
257
258 void print_on(outputStream* st) const;
259 void verify();
260 };
261 106
262 107
263 // Pointer to list of Metachunks. 108 // Pointer to list of Metachunks.
264 class ChunkList VALUE_OBJ_CLASS_SPEC { 109 class ChunkList VALUE_OBJ_CLASS_SPEC {
265 // List of free chunks 110 // List of free chunks
290 135
291 // Free list of chunks of different sizes. 136 // Free list of chunks of different sizes.
292 // SmallChunk 137 // SmallChunk
293 // MediumChunk 138 // MediumChunk
294 // HumongousChunk 139 // HumongousChunk
295 ChunkList _free_chunks[3]; 140 ChunkList _free_chunks[NumberOfFreeLists];
141
142 // HumongousChunk
143 ChunkTreeDictionary _humongous_dictionary;
296 144
297 // ChunkManager in all lists of this type 145 // ChunkManager in all lists of this type
298 size_t _free_chunks_total; 146 size_t _free_chunks_total;
299 size_t _free_chunks_count; 147 size_t _free_chunks_count;
300 148
335 Atomic::add_ptr(count, &_free_chunks_count); 183 Atomic::add_ptr(count, &_free_chunks_count);
336 Atomic::add_ptr(v, &_free_chunks_total); 184 Atomic::add_ptr(v, &_free_chunks_total);
337 } 185 }
338 ChunkList* free_medium_chunks() { return &_free_chunks[1]; } 186 ChunkList* free_medium_chunks() { return &_free_chunks[1]; }
339 ChunkList* free_small_chunks() { return &_free_chunks[0]; } 187 ChunkList* free_small_chunks() { return &_free_chunks[0]; }
340 ChunkList* free_humongous_chunks() { return &_free_chunks[2]; } 188 ChunkTreeDictionary* humongous_dictionary() {
189 return &_humongous_dictionary;
190 }
341 191
342 ChunkList* free_chunks(ChunkIndex index); 192 ChunkList* free_chunks(ChunkIndex index);
343 193
344 // Returns the list for the given chunk word size. 194 // Returns the list for the given chunk word size.
345 ChunkList* find_free_chunks_list(size_t word_size); 195 ChunkList* find_free_chunks_list(size_t word_size);
354 void locked_verify(); 204 void locked_verify();
355 void verify_free_chunks_total(); 205 void verify_free_chunks_total();
356 206
357 void locked_print_free_chunks(outputStream* st); 207 void locked_print_free_chunks(outputStream* st);
358 void locked_print_sum_free_chunks(outputStream* st); 208 void locked_print_sum_free_chunks(outputStream* st);
209
210 void print_on(outputStream* st);
359 }; 211 };
360 212
361 213
362 // Used to manage the free list of Metablocks (a block corresponds 214 // Used to manage the free list of Metablocks (a block corresponds
363 // to the allocation of a quantum of metadata). 215 // to the allocation of a quantum of metadata).
364 class BlockFreelist VALUE_OBJ_CLASS_SPEC { 216 class BlockFreelist VALUE_OBJ_CLASS_SPEC {
365 #ifdef DEALLOCATE_BLOCKS 217 BlockTreeDictionary* _dictionary;
366 BinaryTreeDictionary<Metablock>* _dictionary; 218 static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size);
367 #endif 219
368 static Metablock* initialize_free_chunk(Metablock* block, size_t word_size);
369
370 #ifdef DEALLOCATE_BLOCKS
371 // Accessors 220 // Accessors
372 BinaryTreeDictionary<Metablock>* dictionary() const { return _dictionary; } 221 BlockTreeDictionary* dictionary() const { return _dictionary; }
373 #endif
374 222
375 public: 223 public:
376 BlockFreelist(); 224 BlockFreelist();
377 ~BlockFreelist(); 225 ~BlockFreelist();
378 226
379 // Get and return a block to the free list 227 // Get and return a block to the free list
380 Metablock* get_block(size_t word_size); 228 MetaWord* get_block(size_t word_size);
381 void return_block(Metablock* block, size_t word_size); 229 void return_block(MetaWord* p, size_t word_size);
382 230
383 size_t totalSize() { 231 size_t total_size() {
384 #ifdef DEALLOCATE_BLOCKS 232 if (dictionary() == NULL) {
385 if (dictionary() == NULL) {
386 return 0;
387 } else {
388 return dictionary()->totalSize();
389 }
390 #else
391 return 0; 233 return 0;
392 #endif 234 } else {
393 } 235 return dictionary()->total_size();
236 }
237 }
394 238
395 void print_on(outputStream* st) const; 239 void print_on(outputStream* st) const;
396 }; 240 };
397 241
398 class VirtualSpaceNode : public CHeapObj<mtClass> { 242 class VirtualSpaceNode : public CHeapObj<mtClass> {
598 return result; 442 return result;
599 } 443 }
600 }; 444 };
601 }; 445 };
602 446
603
604 class Metadebug : AllStatic { 447 class Metadebug : AllStatic {
605 // Debugging support for Metaspaces 448 // Debugging support for Metaspaces
606 static int _deallocate_block_a_lot_count; 449 static int _deallocate_block_a_lot_count;
607 static int _deallocate_chunk_a_lot_count; 450 static int _deallocate_chunk_a_lot_count;
608 static int _allocation_fail_alot_count; 451 static int _allocation_fail_alot_count;
653 Mutex* const _lock; 496 Mutex* const _lock;
654 497
655 // List of chunks in use by this SpaceManager. Allocations 498 // List of chunks in use by this SpaceManager. Allocations
656 // are done from the current chunk. The list is used for deallocating 499 // are done from the current chunk. The list is used for deallocating
657 // chunks when the SpaceManager is freed. 500 // chunks when the SpaceManager is freed.
658 Metachunk* _chunks_in_use[NumberOfFreeLists]; 501 Metachunk* _chunks_in_use[NumberOfInUseLists];
659 Metachunk* _current_chunk; 502 Metachunk* _current_chunk;
660 503
661 // Virtual space where allocation comes from. 504 // Virtual space where allocation comes from.
662 VirtualSpaceList* _vs_list; 505 VirtualSpaceList* _vs_list;
663 506
698 Metachunk* find_current_chunk(size_t word_size); 541 Metachunk* find_current_chunk(size_t word_size);
699 542
700 // Add chunk to the list of chunks in use 543 // Add chunk to the list of chunks in use
701 void add_chunk(Metachunk* v, bool make_current); 544 void add_chunk(Metachunk* v, bool make_current);
702 545
703 // Debugging support
704 void verify_chunks_in_use_index(ChunkIndex index, Metachunk* v) {
705 switch (index) {
706 case 0:
707 assert(v->word_size() == SmallChunk, "Not a SmallChunk");
708 break;
709 case 1:
710 assert(v->word_size() == MediumChunk, "Not a MediumChunk");
711 break;
712 case 2:
713 assert(v->word_size() > MediumChunk, "Not a HumongousChunk");
714 break;
715 default:
716 assert(false, "Wrong list.");
717 }
718 }
719
720 protected:
721 Mutex* lock() const { return _lock; } 546 Mutex* lock() const { return _lock; }
722 547
723 public: 548 public:
724 SpaceManager(Mutex* lock, VirtualSpaceList* vs_list); 549 SpaceManager(Mutex* lock, VirtualSpaceList* vs_list);
725 ~SpaceManager(); 550 ~SpaceManager();
749 // Block allocation and deallocation. 574 // Block allocation and deallocation.
750 // Allocates a block from the current chunk 575 // Allocates a block from the current chunk
751 MetaWord* allocate(size_t word_size); 576 MetaWord* allocate(size_t word_size);
752 577
753 // Helper for allocations 578 // Helper for allocations
754 Metablock* allocate_work(size_t word_size); 579 MetaWord* allocate_work(size_t word_size);
755 580
756 // Returns a block to the per manager freelist 581 // Returns a block to the per manager freelist
757 void deallocate(MetaWord* p); 582 void deallocate(MetaWord* p, size_t word_size);
758 583
759 // Based on the allocation size and a minimum chunk size, 584 // Based on the allocation size and a minimum chunk size,
760 // returned chunk size (for expanding space for chunk allocation). 585 // returned chunk size (for expanding space for chunk allocation).
761 size_t calc_chunk_size(size_t allocation_word_size); 586 size_t calc_chunk_size(size_t allocation_word_size);
762 587
763 // Called when an allocation from the current chunk fails. 588 // Called when an allocation from the current chunk fails.
764 // Gets a new chunk (may require getting a new virtual space), 589 // Gets a new chunk (may require getting a new virtual space),
765 // and allocates from that chunk. 590 // and allocates from that chunk.
766 Metablock* grow_and_allocate(size_t word_size); 591 MetaWord* grow_and_allocate(size_t word_size);
767 592
768 // debugging support. 593 // debugging support.
769 594
770 void dump(outputStream* const out) const; 595 void dump(outputStream* const out) const;
771 void print_on(outputStream* st) const; 596 void print_on(outputStream* st) const;
777 void verify_allocation_total(); 602 void verify_allocation_total();
778 #endif 603 #endif
779 }; 604 };
780 605
781 uint const SpaceManager::_small_chunk_limit = 4; 606 uint const SpaceManager::_small_chunk_limit = 4;
607
608
782 609
783 const char* SpaceManager::_expand_lock_name = 610 const char* SpaceManager::_expand_lock_name =
784 "SpaceManager chunk allocation lock"; 611 "SpaceManager chunk allocation lock";
785 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1; 612 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
786 Mutex* const SpaceManager::_expand_lock = 613 Mutex* const SpaceManager::_expand_lock =
787 new Mutex(SpaceManager::_expand_lock_rank, 614 new Mutex(SpaceManager::_expand_lock_rank,
788 SpaceManager::_expand_lock_name, 615 SpaceManager::_expand_lock_name,
789 Mutex::_allow_vm_block_flag); 616 Mutex::_allow_vm_block_flag);
790 617
791 #ifdef ASSERT
792 size_t Metablock::_overhead =
793 Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord;
794 #else
795 size_t Metablock::_overhead = 0;
796 #endif
797 size_t Metachunk::_overhead = 618 size_t Metachunk::_overhead =
798 Chunk::aligned_overhead_size(sizeof(Metachunk)) / BytesPerWord; 619 Chunk::aligned_overhead_size(sizeof(Metachunk)) / BytesPerWord;
799 620
800 // New blocks returned by the Metaspace are zero initialized. 621 // New blocks returned by the Metaspace are zero initialized.
801 // We should fix the constructors to not assume this instead. 622 // We should fix the constructors to not assume this instead.
802 Metablock* Metablock::initialize(MetaWord* p, size_t word_size) { 623 Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {
624 if (p == NULL) {
625 return NULL;
626 }
627
803 Metablock* result = (Metablock*) p; 628 Metablock* result = (Metablock*) p;
804 629
805 // Clear the memory 630 // Clear the memory
806 Copy::fill_to_aligned_words((HeapWord*)result, word_size); 631 Copy::fill_to_aligned_words((HeapWord*)result, word_size);
807 #ifdef ASSERT 632 #ifdef ASSERT
808 result->set_word_size(word_size); 633 result->set_word_size(word_size);
809 // Check after work size is set.
810 result->set_leader((void*) metaspace_allocation_leader);
811 result->set_trailer((void*) metaspace_allocation_trailer);
812 #endif 634 #endif
813 return result; 635 return result;
814 }
815
816 void Metablock::verify() {
817 #ifdef ASSERT
818 assert(leader() == metaspace_allocation_leader &&
819 trailer() == metaspace_allocation_trailer,
820 "block has been corrupted");
821 #endif
822 } 636 }
823 637
824 // Metachunk methods 638 // Metachunk methods
825 639
826 Metachunk* Metachunk::initialize(MetaWord* ptr, size_t word_size) { 640 Metachunk* Metachunk::initialize(MetaWord* ptr, size_t word_size) {
841 #endif 655 #endif
842 return chunk; 656 return chunk;
843 } 657 }
844 658
845 659
846 Metablock* Metachunk::allocate(size_t word_size) { 660 MetaWord* Metachunk::allocate(size_t word_size) {
847 Metablock* result = NULL; 661 MetaWord* result = NULL;
848 // If available, bump the pointer to allocate. 662 // If available, bump the pointer to allocate.
849 if (free_word_size() >= word_size) { 663 if (free_word_size() >= word_size) {
850 result = Metablock::initialize(_top, word_size); 664 result = _top;
851 _top = _top + word_size; 665 _top = _top + word_size;
852 } 666 }
853 #ifdef ASSERT
854 assert(result == NULL ||
855 result->word_size() == word_size,
856 "Block size is not set correctly");
857 #endif
858 return result; 667 return result;
859 } 668 }
860 669
861 // _bottom points to the start of the chunk including the overhead. 670 // _bottom points to the start of the chunk including the overhead.
862 size_t Metachunk::used_word_size() { 671 size_t Metachunk::used_word_size() {
876 " bottom " PTR_FORMAT " top " PTR_FORMAT 685 " bottom " PTR_FORMAT " top " PTR_FORMAT
877 " end " PTR_FORMAT " size " SIZE_FORMAT, 686 " end " PTR_FORMAT " size " SIZE_FORMAT,
878 bottom(), top(), end(), word_size()); 687 bottom(), top(), end(), word_size());
879 } 688 }
880 689
690 #ifdef ASSERT
691 void Metachunk::mangle() {
692 // Mangle the payload of the chunk and not the links that
693 // maintain list of chunks.
694 HeapWord* start = (HeapWord*)(bottom() + overhead());
695 size_t word_size = capacity_word_size() - overhead();
696 Copy::fill_to_words(start, word_size, metadata_chunk_initialize);
697 }
698 #endif // ASSERT
881 699
882 void Metachunk::verify() { 700 void Metachunk::verify() {
883 #ifdef ASSERT 701 #ifdef ASSERT
884 // Cannot walk through the blocks unless the blocks have 702 // Cannot walk through the blocks unless the blocks have
885 // headers with sizes. 703 // headers with sizes.
886 MetaWord* curr = bottom() + overhead(); 704 assert(_bottom <= _top &&
887 while (curr < top()) { 705 _top <= _end,
888 Metablock* block = (Metablock*) curr; 706 "Chunk has been smashed");
889 size_t word_size = block->word_size(); 707 assert(SpaceManager::is_humongous(_word_size) ||
890 block->verify(); 708 _word_size == SpaceManager::MediumChunk ||
891 curr = curr + word_size; 709 _word_size == SpaceManager::SmallChunk,
892 } 710 "Chunk size is wrong");
893 #endif 711 #endif
894 return; 712 return;
895 } 713 }
896 714
897 // BlockFreelist methods 715 // BlockFreelist methods
898 716
899 #ifdef DEALLOCATE_BLOCKS
900 BlockFreelist::BlockFreelist() : _dictionary(NULL) {} 717 BlockFreelist::BlockFreelist() : _dictionary(NULL) {}
901 #else
902 BlockFreelist::BlockFreelist() {}
903 #endif
904 718
905 BlockFreelist::~BlockFreelist() { 719 BlockFreelist::~BlockFreelist() {
906 #ifdef DEALLOCATE_BLOCKS
907 if (_dictionary != NULL) { 720 if (_dictionary != NULL) {
908 if (Verbose && TraceMetadataChunkAllocation) { 721 if (Verbose && TraceMetadataChunkAllocation) {
909 _dictionary->print_free_lists(gclog_or_tty); 722 _dictionary->print_free_lists(gclog_or_tty);
910 } 723 }
911 delete _dictionary; 724 delete _dictionary;
912 } 725 }
913 #endif 726 }
914 } 727
915 728 Metablock* BlockFreelist::initialize_free_chunk(MetaWord* p, size_t word_size) {
916 Metablock* BlockFreelist::initialize_free_chunk(Metablock* block, size_t word_size) { 729 Metablock* block = (Metablock*) p;
917 #ifdef DEALLOCATE_BLOCKS 730 block->set_word_size(word_size);
918 #ifdef ASSERT 731 block->set_prev(NULL);
919 assert(word_size = block->word_size(), "Wrong chunk size"); 732 block->set_next(NULL);
920 #endif 733
921 Metablock* result = block;
922 result->setSize(word_size);
923 result->linkPrev(NULL);
924 result->linkNext(NULL);
925
926 return result;
927 #else
928 ShouldNotReachHere();
929 return block; 734 return block;
930 #endif 735 }
931 } 736
932 737 void BlockFreelist::return_block(MetaWord* p, size_t word_size) {
933 void BlockFreelist::return_block(Metablock* block, size_t word_size) { 738 Metablock* free_chunk = initialize_free_chunk(p, word_size);
934 #ifdef ASSERT
935 assert(word_size = block->word_size(), "Block size is wrong");;
936 #endif
937 Metablock* free_chunk = initialize_free_chunk(block, word_size);
938 #ifdef DEALLOCATE_BLOCKS
939 if (dictionary() == NULL) { 739 if (dictionary() == NULL) {
940 _dictionary = new BinaryTreeDictionary<Metablock>(false /* adaptive_freelists */); 740 _dictionary = new BlockTreeDictionary();
941 } 741 }
942 dictionary()->returnChunk(free_chunk); 742 dictionary()->return_chunk(free_chunk);
943 #endif 743 }
944 } 744
945 745 MetaWord* BlockFreelist::get_block(size_t word_size) {
946 Metablock* BlockFreelist::get_block(size_t word_size) {
947 #ifdef DEALLOCATE_BLOCKS
948 if (dictionary() == NULL) { 746 if (dictionary() == NULL) {
949 return NULL; 747 return NULL;
950 } 748 }
951 749
952 Metablock* free_chunk = 750 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) {
953 dictionary()->getChunk(word_size, FreeBlockDictionary<Metablock>::exactly); 751 // Dark matter. Too small for dictionary.
954 #else
955 Metablock* free_chunk = NULL;
956 #endif
957 if (free_chunk == NULL) {
958 return NULL; 752 return NULL;
959 } 753 }
960 assert(free_chunk->word_size() == word_size, "Size of chunk is incorrect"); 754
961 Metablock* block = Metablock::initialize((MetaWord*) free_chunk, word_size); 755 Metablock* free_block =
962 #ifdef ASSERT 756 dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::exactly);
963 assert(block->word_size() == word_size, "Block size is not set correctly"); 757 if (free_block == NULL) {
964 #endif 758 return NULL;
965 759 }
966 return block; 760
761 return (MetaWord*) free_block;
967 } 762 }
968 763
969 void BlockFreelist::print_on(outputStream* st) const { 764 void BlockFreelist::print_on(outputStream* st) const {
970 #ifdef DEALLOCATE_BLOCKS
971 if (dictionary() == NULL) { 765 if (dictionary() == NULL) {
972 return; 766 return;
973 } 767 }
974 dictionary()->print_free_lists(st); 768 dictionary()->print_free_lists(st);
975 #else
976 return;
977 #endif
978 } 769 }
979 770
980 // VirtualSpaceNode methods 771 // VirtualSpaceNode methods
981 772
982 VirtualSpaceNode::~VirtualSpaceNode() { 773 VirtualSpaceNode::~VirtualSpaceNode() {
1595 #ifdef ASSERT 1386 #ifdef ASSERT
1596 if (MetaDataDeallocateALot && 1387 if (MetaDataDeallocateALot &&
1597 Metadebug::deallocate_block_a_lot_count() % MetaDataDeallocateALotInterval == 0 ) { 1388 Metadebug::deallocate_block_a_lot_count() % MetaDataDeallocateALotInterval == 0 ) {
1598 Metadebug::set_deallocate_block_a_lot_count(0); 1389 Metadebug::set_deallocate_block_a_lot_count(0);
1599 for (uint i = 0; i < metadata_deallocate_a_lot_block; i++) { 1390 for (uint i = 0; i < metadata_deallocate_a_lot_block; i++) {
1600 Metablock* dummy_block = sm->allocate_work(raw_word_size); 1391 MetaWord* dummy_block = sm->allocate_work(raw_word_size);
1601 if (dummy_block == 0) { 1392 if (dummy_block == 0) {
1602 break; 1393 break;
1603 } 1394 }
1604 #ifdef ASSERT 1395 sm->deallocate(dummy_block, raw_word_size);
1605 assert(dummy_block->word_size() == raw_word_size, "Block size is not set correctly");
1606 #endif
1607 sm->deallocate(dummy_block->data());
1608 } 1396 }
1609 } else { 1397 } else {
1610 Metadebug::inc_deallocate_block_a_lot_count(); 1398 Metadebug::inc_deallocate_block_a_lot_count();
1611 } 1399 }
1612 #endif 1400 #endif
1782 } 1570 }
1783 #endif 1571 #endif
1784 } 1572 }
1785 1573
1786 void ChunkManager::locked_verify() { 1574 void ChunkManager::locked_verify() {
1575 locked_verify_free_chunks_count();
1787 locked_verify_free_chunks_total(); 1576 locked_verify_free_chunks_total();
1788 locked_verify_free_chunks_count();
1789 } 1577 }
1790 1578
1791 void ChunkManager::locked_print_free_chunks(outputStream* st) { 1579 void ChunkManager::locked_print_free_chunks(outputStream* st) {
1792 assert_lock_strong(SpaceManager::expand_lock()); 1580 assert_lock_strong(SpaceManager::expand_lock());
1793 st->print_cr("Free chunk total 0x%x count 0x%x", 1581 st->print_cr("Free chunk total 0x%x count 0x%x",
1800 sum_free_chunks(), sum_free_chunks_count()); 1588 sum_free_chunks(), sum_free_chunks_count());
1801 } 1589 }
1802 ChunkList* ChunkManager::free_chunks(ChunkIndex index) { 1590 ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
1803 return &_free_chunks[index]; 1591 return &_free_chunks[index];
1804 } 1592 }
1805
1806 1593
1807 // These methods that sum the free chunk lists are used in printing 1594 // These methods that sum the free chunk lists are used in printing
1808 // methods that are used in product builds. 1595 // methods that are used in product builds.
1809 size_t ChunkManager::sum_free_chunks() { 1596 size_t ChunkManager::sum_free_chunks() {
1810 assert_lock_strong(SpaceManager::expand_lock()); 1597 assert_lock_strong(SpaceManager::expand_lock());
1816 continue; 1603 continue;
1817 } 1604 }
1818 1605
1819 result = result + list->sum_list_capacity(); 1606 result = result + list->sum_list_capacity();
1820 } 1607 }
1608 result = result + humongous_dictionary()->total_size();
1821 return result; 1609 return result;
1822 } 1610 }
1823 1611
1824 size_t ChunkManager::sum_free_chunks_count() { 1612 size_t ChunkManager::sum_free_chunks_count() {
1825 assert_lock_strong(SpaceManager::expand_lock()); 1613 assert_lock_strong(SpaceManager::expand_lock());
1829 if (list == NULL) { 1617 if (list == NULL) {
1830 continue; 1618 continue;
1831 } 1619 }
1832 count = count + list->sum_list_count(); 1620 count = count + list->sum_list_count();
1833 } 1621 }
1622 count = count + humongous_dictionary()->total_free_blocks();
1834 return count; 1623 return count;
1835 } 1624 }
1836 1625
1837 ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) { 1626 ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) {
1838 switch (word_size) { 1627 switch (word_size) {
1873 1662
1874 Metachunk* ChunkManager::free_chunks_get(size_t word_size) { 1663 Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
1875 assert_lock_strong(SpaceManager::expand_lock()); 1664 assert_lock_strong(SpaceManager::expand_lock());
1876 1665
1877 locked_verify(); 1666 locked_verify();
1878 ChunkList* free_list = find_free_chunks_list(word_size); 1667
1879 assert(free_list != NULL, "Sanity check"); 1668 Metachunk* chunk = NULL;
1880 1669 if (!SpaceManager::is_humongous(word_size)) {
1881 Metachunk* chunk = free_list->head(); 1670 ChunkList* free_list = find_free_chunks_list(word_size);
1882 debug_only(Metachunk* debug_head = chunk;) 1671 assert(free_list != NULL, "Sanity check");
1883 1672
1884 if (chunk == NULL) { 1673 chunk = free_list->head();
1885 return NULL; 1674 debug_only(Metachunk* debug_head = chunk;)
1886 } 1675
1887 1676 if (chunk == NULL) {
1888 Metachunk* prev_chunk = chunk; 1677 return NULL;
1889 if (chunk->word_size() == word_size) { 1678 }
1890 // Chunk is being removed from the chunks free list. 1679
1891 dec_free_chunks_total(chunk->capacity_word_size());
1892 // Remove the chunk as the head of the list. 1680 // Remove the chunk as the head of the list.
1893 free_list->set_head(chunk->next()); 1681 free_list->set_head(chunk->next());
1894 chunk->set_next(NULL); 1682 chunk->set_next(NULL);
1683 // Chunk has been removed from the chunks free list.
1684 dec_free_chunks_total(chunk->capacity_word_size());
1895 1685
1896 if (TraceMetadataChunkAllocation && Verbose) { 1686 if (TraceMetadataChunkAllocation && Verbose) {
1897 tty->print_cr("ChunkManager::free_chunks_get: free_list " 1687 tty->print_cr("ChunkManager::free_chunks_get: free_list "
1898 PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT, 1688 PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
1899 free_list, chunk, chunk->word_size()); 1689 free_list, chunk, chunk->word_size());
1900 } 1690 }
1901 } else { 1691 } else {
1902 assert(SpaceManager::is_humongous(word_size), 1692 chunk = humongous_dictionary()->get_chunk(
1903 "Should only need to check humongous"); 1693 word_size,
1904 // This code to find the best fit is just for purposes of 1694 FreeBlockDictionary<Metachunk>::atLeast);
1905 // investigating the loss due to fragmentation on a humongous 1695
1906 // chunk. It will be replace by a binaryTreeDictionary for 1696 if (chunk != NULL) {
1907 // the humongous chunks. 1697 if (TraceMetadataHumongousAllocation) {
1908 uint count = 0; 1698 size_t waste = chunk->word_size() - word_size;
1909 Metachunk* best_fit = NULL; 1699 tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT
1910 Metachunk* best_fit_prev = NULL; 1700 " for requested size " SIZE_FORMAT
1911 while (chunk != NULL) { 1701 " waste " SIZE_FORMAT,
1912 count++; 1702 chunk->word_size(), word_size, waste);
1913 if (chunk->word_size() < word_size) {
1914 prev_chunk = chunk;
1915 chunk = chunk->next();
1916 } else if (chunk->word_size() == word_size) {
1917 break;
1918 } else {
1919 if (best_fit == NULL ||
1920 best_fit->word_size() > chunk->word_size()) {
1921 best_fit_prev = prev_chunk;
1922 best_fit = chunk;
1923 }
1924 prev_chunk = chunk;
1925 chunk = chunk->next();
1926 } 1703 }
1927 } 1704 // Chunk is being removed from the chunks free list.
1928 if (chunk == NULL) { 1705 dec_free_chunks_total(chunk->capacity_word_size());
1929 prev_chunk = best_fit_prev; 1706 #ifdef ASSERT
1930 chunk = best_fit; 1707 chunk->set_is_free(false);
1931 } 1708 #endif
1932 if (chunk != NULL) { 1709 }
1933 if (TraceMetadataHumongousAllocation) {
1934 size_t waste = chunk->word_size() - word_size;
1935 tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT
1936 " for requested size " SIZE_FORMAT
1937 " waste " SIZE_FORMAT
1938 " found at " SIZE_FORMAT " of " SIZE_FORMAT,
1939 chunk->word_size(), word_size, waste,
1940 count, free_list->sum_list_count());
1941 }
1942 // Chunk is being removed from the chunks free list.
1943 dec_free_chunks_total(chunk->capacity_word_size());
1944 // Remove the chunk if it is at the head of the list.
1945 if (chunk == free_list->head()) {
1946 free_list->set_head(chunk->next());
1947
1948 if (TraceMetadataHumongousAllocation) {
1949 tty->print_cr("ChunkManager::free_chunks_get: humongous free_list "
1950 PTR_FORMAT " chunk " PTR_FORMAT " size " SIZE_FORMAT
1951 " new head " PTR_FORMAT,
1952 free_list, chunk, chunk->word_size(),
1953 free_list->head());
1954 }
1955 } else {
1956 // Remove a chunk in the interior of the list
1957 prev_chunk->set_next(chunk->next());
1958
1959 if (TraceMetadataHumongousAllocation) {
1960 tty->print_cr("ChunkManager::free_chunks_get: humongous free_list "
1961 PTR_FORMAT " chunk " PTR_FORMAT " size " SIZE_FORMAT
1962 PTR_FORMAT " prev " PTR_FORMAT " next " PTR_FORMAT,
1963 free_list, chunk, chunk->word_size(),
1964 prev_chunk, chunk->next());
1965 }
1966 }
1967 chunk->set_next(NULL);
1968 } else {
1969 if (TraceMetadataHumongousAllocation) {
1970 tty->print_cr("ChunkManager::free_chunks_get: New humongous chunk of size "
1971 SIZE_FORMAT,
1972 word_size);
1973 }
1974 }
1975 } 1710 }
1976 locked_verify(); 1711 locked_verify();
1977 return chunk; 1712 return chunk;
1978 } 1713 }
1979 1714
1998 } 1733 }
1999 1734
2000 return chunk; 1735 return chunk;
2001 } 1736 }
2002 1737
1738 void ChunkManager::print_on(outputStream* out) {
1739 if (PrintFLSStatistics != 0) {
1740 humongous_dictionary()->report_statistics();
1741 }
1742 }
1743
2003 // SpaceManager methods 1744 // SpaceManager methods
2004 1745
2005 size_t SpaceManager::sum_free_in_chunks_in_use() const { 1746 size_t SpaceManager::sum_free_in_chunks_in_use() const {
2006 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1747 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2007 size_t free = 0; 1748 size_t free = 0;
2008 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1749 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2009 Metachunk* chunk = chunks_in_use(i); 1750 Metachunk* chunk = chunks_in_use(i);
2010 while (chunk != NULL) { 1751 while (chunk != NULL) {
2011 free += chunk->free_word_size(); 1752 free += chunk->free_word_size();
2012 chunk = chunk->next(); 1753 chunk = chunk->next();
2013 } 1754 }
2016 } 1757 }
2017 1758
2018 size_t SpaceManager::sum_waste_in_chunks_in_use() const { 1759 size_t SpaceManager::sum_waste_in_chunks_in_use() const {
2019 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1760 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2020 size_t result = 0; 1761 size_t result = 0;
2021 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1762 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2022 // Count the free space in all the chunk but not the 1763
2023 // current chunk from which allocations are still being done. 1764
2024 result += sum_waste_in_chunks_in_use(i); 1765 result += sum_waste_in_chunks_in_use(i);
2025 } 1766 }
1767
2026 return result; 1768 return result;
2027 } 1769 }
2028 1770
2029 size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { 1771 size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const {
2030 size_t result = 0; 1772 size_t result = 0;
2031 size_t count = 0; 1773 size_t count = 0;
2032 Metachunk* chunk = chunks_in_use(index); 1774 Metachunk* chunk = chunks_in_use(index);
2033 // Count the free space in all the chunk but not the 1775 // Count the free space in all the chunk but not the
2034 // current chunk from which allocations are still being done. 1776 // current chunk from which allocations are still being done.
2035 if (chunk != NULL) { 1777 if (chunk != NULL) {
2036 while (chunk != NULL) { 1778 Metachunk* prev = chunk;
2037 if (chunk != current_chunk()) { 1779 while (chunk != NULL && chunk != current_chunk()) {
2038 result += chunk->free_word_size(); 1780 result += chunk->free_word_size();
2039 } 1781 prev = chunk;
2040 chunk = chunk->next(); 1782 chunk = chunk->next();
2041 count++; 1783 count++;
2042 } 1784 }
2043 } 1785 }
2044 return result; 1786 return result;
2045 } 1787 }
2046 1788
2047 size_t SpaceManager::sum_capacity_in_chunks_in_use() const { 1789 size_t SpaceManager::sum_capacity_in_chunks_in_use() const {
2048 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1790 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2049 size_t sum = 0; 1791 size_t sum = 0;
2050 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1792 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2051 Metachunk* chunk = chunks_in_use(i); 1793 Metachunk* chunk = chunks_in_use(i);
2052 while (chunk != NULL) { 1794 while (chunk != NULL) {
2053 // Just changed this sum += chunk->capacity_word_size(); 1795 // Just changed this sum += chunk->capacity_word_size();
2054 // sum += chunk->word_size() - Metachunk::overhead(); 1796 // sum += chunk->word_size() - Metachunk::overhead();
2055 sum += chunk->capacity_word_size(); 1797 sum += chunk->capacity_word_size();
2059 return sum; 1801 return sum;
2060 } 1802 }
2061 1803
2062 size_t SpaceManager::sum_count_in_chunks_in_use() { 1804 size_t SpaceManager::sum_count_in_chunks_in_use() {
2063 size_t count = 0; 1805 size_t count = 0;
2064 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1806 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2065 count = count + sum_count_in_chunks_in_use(i); 1807 count = count + sum_count_in_chunks_in_use(i);
2066 } 1808 }
1809
2067 return count; 1810 return count;
2068 } 1811 }
2069 1812
2070 size_t SpaceManager::sum_count_in_chunks_in_use(ChunkIndex i) { 1813 size_t SpaceManager::sum_count_in_chunks_in_use(ChunkIndex i) {
2071 size_t count = 0; 1814 size_t count = 0;
2079 1822
2080 1823
2081 size_t SpaceManager::sum_used_in_chunks_in_use() const { 1824 size_t SpaceManager::sum_used_in_chunks_in_use() const {
2082 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1825 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2083 size_t used = 0; 1826 size_t used = 0;
2084 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1827 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2085 Metachunk* chunk = chunks_in_use(i); 1828 Metachunk* chunk = chunks_in_use(i);
2086 while (chunk != NULL) { 1829 while (chunk != NULL) {
2087 used += chunk->used_word_size(); 1830 used += chunk->used_word_size();
2088 chunk = chunk->next(); 1831 chunk = chunk->next();
2089 } 1832 }
2137 SpaceManager::is_humongous(word_size)) { 1880 SpaceManager::is_humongous(word_size)) {
2138 gclog_or_tty->print_cr("Metadata humongous allocation:"); 1881 gclog_or_tty->print_cr("Metadata humongous allocation:");
2139 gclog_or_tty->print_cr(" word_size " PTR_FORMAT, word_size); 1882 gclog_or_tty->print_cr(" word_size " PTR_FORMAT, word_size);
2140 gclog_or_tty->print_cr(" chunk_word_size " PTR_FORMAT, 1883 gclog_or_tty->print_cr(" chunk_word_size " PTR_FORMAT,
2141 chunk_word_size); 1884 chunk_word_size);
2142 gclog_or_tty->print_cr(" block overhead " PTR_FORMAT 1885 gclog_or_tty->print_cr(" chunk overhead " PTR_FORMAT,
2143 " chunk overhead " PTR_FORMAT,
2144 Metablock::overhead(),
2145 Metachunk::overhead()); 1886 Metachunk::overhead());
2146 } 1887 }
2147 return chunk_word_size; 1888 return chunk_word_size;
2148 } 1889 }
2149 1890
2150 Metablock* SpaceManager::grow_and_allocate(size_t word_size) { 1891 MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
2151 assert(vs_list()->current_virtual_space() != NULL, 1892 assert(vs_list()->current_virtual_space() != NULL,
2152 "Should have been set"); 1893 "Should have been set");
2153 assert(current_chunk() == NULL || 1894 assert(current_chunk() == NULL ||
2154 current_chunk()->allocate(word_size) == NULL, 1895 current_chunk()->allocate(word_size) == NULL,
2155 "Don't need to expand"); 1896 "Don't need to expand");
2178 } 1919 }
2179 1920
2180 void SpaceManager::print_on(outputStream* st) const { 1921 void SpaceManager::print_on(outputStream* st) const {
2181 1922
2182 for (ChunkIndex i = SmallIndex; 1923 for (ChunkIndex i = SmallIndex;
2183 i < NumberOfFreeLists ; 1924 i < NumberOfInUseLists ;
2184 i = next_chunk_index(i) ) { 1925 i = next_chunk_index(i) ) {
2185 st->print_cr(" chunks_in_use " PTR_FORMAT " chunk size " PTR_FORMAT, 1926 st->print_cr(" chunks_in_use " PTR_FORMAT " chunk size " PTR_FORMAT,
2186 chunks_in_use(i), 1927 chunks_in_use(i),
2187 chunks_in_use(i) == NULL ? 0 : chunks_in_use(i)->word_size()); 1928 chunks_in_use(i) == NULL ? 0 : chunks_in_use(i)->word_size());
2188 } 1929 }
2189 st->print_cr(" waste: Small " SIZE_FORMAT " Medium " SIZE_FORMAT 1930 st->print_cr(" waste: Small " SIZE_FORMAT " Medium " SIZE_FORMAT
2190 " Humongous " SIZE_FORMAT, 1931 " Humongous " SIZE_FORMAT,
2191 sum_waste_in_chunks_in_use(SmallIndex), 1932 sum_waste_in_chunks_in_use(SmallIndex),
2192 sum_waste_in_chunks_in_use(MediumIndex), 1933 sum_waste_in_chunks_in_use(MediumIndex),
2193 sum_waste_in_chunks_in_use(HumongousIndex)); 1934 sum_waste_in_chunks_in_use(HumongousIndex));
2194 // Nothing in them yet 1935 // block free lists
2195 // block_freelists()->print_on(st); 1936 if (block_freelists() != NULL) {
1937 st->print_cr("total in block free lists " SIZE_FORMAT,
1938 block_freelists()->total_size());
1939 }
2196 } 1940 }
2197 1941
2198 SpaceManager::SpaceManager(Mutex* lock, VirtualSpaceList* vs_list) : 1942 SpaceManager::SpaceManager(Mutex* lock, VirtualSpaceList* vs_list) :
2199 _vs_list(vs_list), 1943 _vs_list(vs_list),
2200 _allocation_total(0), 1944 _allocation_total(0),
2201 _lock(lock) { 1945 _lock(lock) {
2202 Metadebug::init_allocation_fail_alot_count(); 1946 Metadebug::init_allocation_fail_alot_count();
2203 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1947 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2204 _chunks_in_use[i] = NULL; 1948 _chunks_in_use[i] = NULL;
2205 } 1949 }
2206 _current_chunk = NULL; 1950 _current_chunk = NULL;
2207 if (TraceMetadataChunkAllocation && Verbose) { 1951 if (TraceMetadataChunkAllocation && Verbose) {
2208 gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, this); 1952 gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, this);
2260 2004
2261 // Humongous chunks 2005 // Humongous chunks
2262 // Humongous chunks are never the current chunk. 2006 // Humongous chunks are never the current chunk.
2263 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); 2007 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
2264 2008
2265 if (humongous_chunks != NULL) { 2009 while (humongous_chunks != NULL) {
2266 chunk_manager->free_humongous_chunks()->add_at_head(humongous_chunks); 2010 #ifdef ASSERT
2267 set_chunks_in_use(HumongousIndex, NULL); 2011 humongous_chunks->set_is_free(true);
2268 } 2012 #endif
2013 Metachunk* next_humongous_chunks = humongous_chunks->next();
2014 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks);
2015 humongous_chunks = next_humongous_chunks;
2016 }
2017 set_chunks_in_use(HumongousIndex, NULL);
2269 chunk_manager->locked_verify(); 2018 chunk_manager->locked_verify();
2270 } 2019 }
2271 2020
2272 void SpaceManager::deallocate(MetaWord* p) { 2021 void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
2273 assert_lock_strong(_lock); 2022 assert_lock_strong(_lock);
2274 ShouldNotReachHere(); // Where is this needed. 2023 size_t min_size = TreeChunk<Metablock, FreeList>::min_size();
2275 #ifdef DEALLOCATE_BLOCKS 2024 assert(word_size >= min_size,
2276 Metablock* block = Metablock::metablock_from_data(p); 2025 err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size));
2277 // This is expense but kept it until integration JJJ 2026 block_freelists()->return_block(p, word_size);
2278 assert(contains((address)block), "Block does not belong to this metaspace");
2279 block_freelists()->return_block(block, word_size);
2280 #endif
2281 } 2027 }
2282 2028
2283 // Adds a chunk to the list of chunks in use. 2029 // Adds a chunk to the list of chunks in use.
2284 void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { 2030 void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
2285 2031
2364 } 2110 }
2365 2111
2366 MetaWord* SpaceManager::allocate(size_t word_size) { 2112 MetaWord* SpaceManager::allocate(size_t word_size) {
2367 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 2113 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2368 2114
2369 size_t block_overhead = Metablock::overhead();
2370 // If only the dictionary is going to be used (i.e., no 2115 // If only the dictionary is going to be used (i.e., no
2371 // indexed free list), then there is a minimum size requirement. 2116 // indexed free list), then there is a minimum size requirement.
2372 // MinChunkSize is a placeholder for the real minimum size JJJ 2117 // MinChunkSize is a placeholder for the real minimum size JJJ
2373 size_t byte_size_with_overhead = (word_size + block_overhead) * BytesPerWord; 2118 size_t byte_size = word_size * BytesPerWord;
2374 #ifdef DEALLOCATE_BLOCKS 2119
2375 size_t raw_bytes_size = MAX2(ARENA_ALIGN(byte_size_with_overhead), 2120 size_t byte_size_with_overhead = byte_size + Metablock::overhead();
2376 MinChunkSize * BytesPerWord); 2121
2377 #else 2122 size_t raw_bytes_size = MAX2(byte_size_with_overhead,
2378 size_t raw_bytes_size = ARENA_ALIGN(byte_size_with_overhead); 2123 Metablock::min_block_byte_size());
2379 #endif 2124 raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
2380 size_t raw_word_size = raw_bytes_size / BytesPerWord; 2125 size_t raw_word_size = raw_bytes_size / BytesPerWord;
2381 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); 2126 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
2382 2127
2383 BlockFreelist* fl = block_freelists(); 2128 BlockFreelist* fl = block_freelists();
2384 Metablock* block = NULL; 2129 MetaWord* p = NULL;
2385 // Allocation from the dictionary is expensive in the sense that 2130 // Allocation from the dictionary is expensive in the sense that
2386 // the dictionary has to be searched for a size. Don't allocate 2131 // the dictionary has to be searched for a size. Don't allocate
2387 // from the dictionary until it starts to get fat. Is this 2132 // from the dictionary until it starts to get fat. Is this
2388 // a reasonable policy? Maybe an skinny dictionary is fast enough 2133 // a reasonable policy? Maybe an skinny dictionary is fast enough
2389 // for allocations. Do some profiling. JJJ 2134 // for allocations. Do some profiling. JJJ
2390 if (fl->totalSize() > allocation_from_dictionary_limit) { 2135 if (fl->total_size() > allocation_from_dictionary_limit) {
2391 block = fl->get_block(raw_word_size); 2136 p = fl->get_block(raw_word_size);
2392 } 2137 }
2393 if (block == NULL) { 2138 if (p == NULL) {
2394 block = allocate_work(raw_word_size); 2139 p = allocate_work(raw_word_size);
2395 if (block == NULL) {
2396 return NULL;
2397 }
2398 } 2140 }
2399 Metadebug::deallocate_block_a_lot(this, raw_word_size); 2141 Metadebug::deallocate_block_a_lot(this, raw_word_size);
2400 2142
2401 // Push the allocation past the word containing the size and leader. 2143 return p;
2402 #ifdef ASSERT
2403 MetaWord* result = block->data();
2404 return result;
2405 #else
2406 return (MetaWord*) block;
2407 #endif
2408 } 2144 }
2409 2145
2410 // Returns the address of spaced allocated for "word_size". 2146 // Returns the address of spaced allocated for "word_size".
2411 // This methods does not know about blocks (Metablocks) 2147 // This methods does not know about blocks (Metablocks)
2412 Metablock* SpaceManager::allocate_work(size_t word_size) { 2148 MetaWord* SpaceManager::allocate_work(size_t word_size) {
2413 assert_lock_strong(_lock); 2149 assert_lock_strong(_lock);
2414 #ifdef ASSERT 2150 #ifdef ASSERT
2415 if (Metadebug::test_metadata_failure()) { 2151 if (Metadebug::test_metadata_failure()) {
2416 return NULL; 2152 return NULL;
2417 } 2153 }
2418 #endif 2154 #endif
2419 // Is there space in the current chunk? 2155 // Is there space in the current chunk?
2420 Metablock* result = NULL; 2156 MetaWord* result = NULL;
2421 2157
2422 // For DumpSharedSpaces, only allocate out of the current chunk which is 2158 // For DumpSharedSpaces, only allocate out of the current chunk which is
2423 // never null because we gave it the size we wanted. Caller reports out 2159 // never null because we gave it the size we wanted. Caller reports out
2424 // of memory if this returns null. 2160 // of memory if this returns null.
2425 if (DumpSharedSpaces) { 2161 if (DumpSharedSpaces) {
2434 if (result == NULL) { 2170 if (result == NULL) {
2435 result = grow_and_allocate(word_size); 2171 result = grow_and_allocate(word_size);
2436 } 2172 }
2437 if (result > 0) { 2173 if (result > 0) {
2438 inc_allocation_total(word_size); 2174 inc_allocation_total(word_size);
2439 assert(result != (Metablock*) chunks_in_use(MediumIndex), "Head of the list is being allocated"); 2175 assert(result != (MetaWord*) chunks_in_use(MediumIndex),
2440 assert(result->word_size() == word_size, "Size not set correctly"); 2176 "Head of the list is being allocated");
2441 } 2177 }
2442 2178
2443 return result; 2179 return result;
2444 } 2180 }
2445 2181
2446 void SpaceManager::verify() { 2182 void SpaceManager::verify() {
2447 // If there are blocks in the dictionary, then 2183 // If there are blocks in the dictionary, then
2448 // verfication of chunks does not work since 2184 // verfication of chunks does not work since
2449 // being in the dictionary alters a chunk. 2185 // being in the dictionary alters a chunk.
2450 if (block_freelists()->totalSize() == 0) { 2186 if (block_freelists()->total_size() == 0) {
2451 // Skip the small chunks because their next link points to 2187 // Skip the small chunks because their next link points to
2452 // medium chunks. This is because the small chunk is the 2188 // medium chunks. This is because the small chunk is the
2453 // current chunk (for allocations) until it is full and the 2189 // current chunk (for allocations) until it is full and the
2454 // the addition of the next chunk does not NULL the next 2190 // the addition of the next chunk does not NULL the next
2455 // like of the small chunk. 2191 // like of the small chunk.
2456 for (ChunkIndex i = MediumIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 2192 for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2457 Metachunk* curr = chunks_in_use(i); 2193 Metachunk* curr = chunks_in_use(i);
2458 while (curr != NULL) { 2194 while (curr != NULL) {
2459 curr->verify(); 2195 curr->verify();
2460 curr = curr->next(); 2196 curr = curr->next();
2461 } 2197 }
2490 size_t used = 0; 2226 size_t used = 0;
2491 size_t capacity = 0; 2227 size_t capacity = 0;
2492 2228
2493 // Add up statistics for all chunks in this SpaceManager. 2229 // Add up statistics for all chunks in this SpaceManager.
2494 for (ChunkIndex index = SmallIndex; 2230 for (ChunkIndex index = SmallIndex;
2495 index < NumberOfFreeLists; 2231 index < NumberOfInUseLists;
2496 index = next_chunk_index(index)) { 2232 index = next_chunk_index(index)) {
2497 for (Metachunk* curr = chunks_in_use(index); 2233 for (Metachunk* curr = chunks_in_use(index);
2498 curr != NULL; 2234 curr != NULL;
2499 curr = curr->next()) { 2235 curr = curr->next()) {
2500 out->print("%d) ", i++); 2236 out->print("%d) ", i++);
2519 } 2255 }
2520 2256
2521 #ifdef ASSERT 2257 #ifdef ASSERT
2522 void SpaceManager::mangle_freed_chunks() { 2258 void SpaceManager::mangle_freed_chunks() {
2523 for (ChunkIndex index = SmallIndex; 2259 for (ChunkIndex index = SmallIndex;
2524 index < NumberOfFreeLists; 2260 index < NumberOfInUseLists;
2525 index = next_chunk_index(index)) { 2261 index = next_chunk_index(index)) {
2526 for (Metachunk* curr = chunks_in_use(index); 2262 for (Metachunk* curr = chunks_in_use(index);
2527 curr != NULL; 2263 curr != NULL;
2528 curr = curr->next()) { 2264 curr = curr->next()) {
2529 // Try to detect incorrectly terminated small chunk 2265 // Try to detect incorrectly terminated small chunk
2831 if (class_chunk != NULL) { 2567 if (class_chunk != NULL) {
2832 class_vsm()->add_chunk(class_chunk, true); 2568 class_vsm()->add_chunk(class_chunk, true);
2833 } 2569 }
2834 } 2570 }
2835 2571
2836
2837 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { 2572 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
2838 // DumpSharedSpaces doesn't use class metadata area (yet) 2573 // DumpSharedSpaces doesn't use class metadata area (yet)
2839 if (mdtype == ClassType && !DumpSharedSpaces) { 2574 if (mdtype == ClassType && !DumpSharedSpaces) {
2840 return class_vsm()->allocate(word_size); 2575 return class_vsm()->allocate(word_size);
2841 } else { 2576 } else {
2842 return vsm()->allocate(word_size); 2577 return vsm()->allocate(word_size);
2843 } 2578 }
2844 } 2579 }
2845 2580
2846 MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) { 2581 MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) {
2847 MetaWord* result; 2582 MetaWord* result;
2851 MetaspaceGC::inc_capacity_until_GC(delta_words); 2586 MetaspaceGC::inc_capacity_until_GC(delta_words);
2852 if (PrintGCDetails && Verbose) { 2587 if (PrintGCDetails && Verbose) {
2853 gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT 2588 gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
2854 " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC()); 2589 " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC());
2855 } 2590 }
2591
2856 result = allocate(word_size, mdtype); 2592 result = allocate(word_size, mdtype);
2857 2593
2858 return result; 2594 return result;
2859 } 2595 }
2860 2596
2887 } 2623 }
2888 2624
2889 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { 2625 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
2890 if (SafepointSynchronize::is_at_safepoint()) { 2626 if (SafepointSynchronize::is_at_safepoint()) {
2891 assert(Thread::current()->is_VM_thread(), "should be the VM thread"); 2627 assert(Thread::current()->is_VM_thread(), "should be the VM thread");
2892 // Don't take lock 2628 // Don't take Heap_lock
2893 #ifdef DEALLOCATE_BLOCKS 2629 MutexLocker ml(vsm()->lock());
2630 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) {
2631 // Dark matter. Too small for dictionary.
2632 #ifdef ASSERT
2633 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5);
2634 #endif
2635 return;
2636 }
2894 if (is_class) { 2637 if (is_class) {
2895 class_vsm()->deallocate(ptr); 2638 class_vsm()->deallocate(ptr, word_size);
2896 } else { 2639 } else {
2897 vsm()->deallocate(ptr); 2640 vsm()->deallocate(ptr, word_size);
2898 } 2641 }
2899 #else
2900 #ifdef ASSERT
2901 Copy::fill_to_words((HeapWord*)ptr, word_size, metadata_deallocate);
2902 #endif
2903 #endif
2904
2905 } else { 2642 } else {
2906 MutexLocker ml(vsm()->lock()); 2643 MutexLocker ml(vsm()->lock());
2907 2644
2908 #ifdef DEALLOCATE_BLOCKS 2645 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) {
2646 // Dark matter. Too small for dictionary.
2647 #ifdef ASSERT
2648 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5);
2649 #endif
2650 return;
2651 }
2909 if (is_class) { 2652 if (is_class) {
2910 class_vsm()->deallocate(ptr); 2653 class_vsm()->deallocate(ptr, word_size);
2911 } else { 2654 } else {
2912 vsm()->deallocate(ptr); 2655 vsm()->deallocate(ptr, word_size);
2913 } 2656 }
2914 #else 2657 }
2915 #ifdef ASSERT 2658 }
2916 Copy::fill_to_words((HeapWord*)ptr, word_size, metadata_deallocate); 2659
2917 #endif 2660 Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
2918 #endif
2919 }
2920 }
2921
2922 MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
2923 bool read_only, MetadataType mdtype, TRAPS) { 2661 bool read_only, MetadataType mdtype, TRAPS) {
2924 if (HAS_PENDING_EXCEPTION) { 2662 if (HAS_PENDING_EXCEPTION) {
2925 assert(false, "Should not allocate with exception pending"); 2663 assert(false, "Should not allocate with exception pending");
2926 return NULL; // caller does a CHECK_NULL too 2664 return NULL; // caller does a CHECK_NULL too
2927 } 2665 }
2941 result = loader_data->rw_metaspace()->allocate(word_size, NonClassType); 2679 result = loader_data->rw_metaspace()->allocate(word_size, NonClassType);
2942 } 2680 }
2943 if (result == NULL) { 2681 if (result == NULL) {
2944 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); 2682 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
2945 } 2683 }
2946 return result; 2684 return Metablock::initialize(result, word_size);
2947 } 2685 }
2948 2686
2949 result = loader_data->metaspace_non_null()->allocate(word_size, mdtype); 2687 result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
2950 2688
2951 if (result == NULL) { 2689 if (result == NULL) {
2952 // Try to clean out some memory and retry. 2690 // Try to clean out some memory and retry.
2953 result = 2691 result =
2954 Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation( 2692 Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
2955 loader_data, word_size, mdtype); 2693 loader_data, word_size, mdtype);
2956 2694
2957 // If result is still null, we are out of memory. 2695 // If result is still null, we are out of memory.
2958 if (result == NULL) { 2696 if (result == NULL) {
2959 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support 2697 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
2965 "Metadata space"); 2703 "Metadata space");
2966 } 2704 }
2967 THROW_OOP_0(Universe::out_of_memory_error_perm_gen()); 2705 THROW_OOP_0(Universe::out_of_memory_error_perm_gen());
2968 } 2706 }
2969 } 2707 }
2970 return result; 2708 return Metablock::initialize(result, word_size);
2971 } 2709 }
2972 2710
2973 void Metaspace::print_on(outputStream* out) const { 2711 void Metaspace::print_on(outputStream* out) const {
2974 // Print both class virtual space counts and metaspace. 2712 // Print both class virtual space counts and metaspace.
2975 if (Verbose) { 2713 if (Verbose) {