comparison src/share/vm/memory/metaspace.cpp @ 7446:e51c9860cf66

8005082: NPG: Add specialized Metachunk sizes for reflection and anonymous classloaders Reviewed-by: johnc, coleenp
author jmasa
date Mon, 03 Dec 2012 15:09:39 -0800
parents c71879335291
children 1de1b145f6bc
comparison
equal deleted inserted replaced
7445:cd962e15c08e 7446:e51c9860cf66
56 56
57 MetaWord* last_allocated = 0; 57 MetaWord* last_allocated = 0;
58 58
59 // Used in declarations in SpaceManager and ChunkManager 59 // Used in declarations in SpaceManager and ChunkManager
60 enum ChunkIndex { 60 enum ChunkIndex {
61 SmallIndex = 0, 61 ZeroIndex = 0,
62 MediumIndex = 1, 62 SpecializedIndex = ZeroIndex,
63 HumongousIndex = 2, 63 SmallIndex = SpecializedIndex + 1,
64 NumberOfFreeLists = 2, 64 MediumIndex = SmallIndex + 1,
65 NumberOfInUseLists = 3 65 HumongousIndex = MediumIndex + 1,
66 NumberOfFreeLists = 3,
67 NumberOfInUseLists = 4
68 };
69
70 enum ChunkSizes { // in words.
71 ClassSpecializedChunk = 128,
72 SpecializedChunk = 128,
73 ClassSmallChunk = 256,
74 SmallChunk = 512,
75 ClassMediumChunk = 1 * K,
76 MediumChunk = 8 * K,
77 HumongousChunkGranularity = 8
66 }; 78 };
67 79
68 static ChunkIndex next_chunk_index(ChunkIndex i) { 80 static ChunkIndex next_chunk_index(ChunkIndex i) {
69 assert(i < NumberOfInUseLists, "Out of bound"); 81 assert(i < NumberOfInUseLists, "Out of bound");
70 return (ChunkIndex) (i+1); 82 return (ChunkIndex) (i+1);
124 // SmallChunk 136 // SmallChunk
125 // MediumChunk 137 // MediumChunk
126 // HumongousChunk 138 // HumongousChunk
127 ChunkList _free_chunks[NumberOfFreeLists]; 139 ChunkList _free_chunks[NumberOfFreeLists];
128 140
141
129 // HumongousChunk 142 // HumongousChunk
130 ChunkTreeDictionary _humongous_dictionary; 143 ChunkTreeDictionary _humongous_dictionary;
131 144
132 // ChunkManager in all lists of this type 145 // ChunkManager in all lists of this type
133 size_t _free_chunks_total; 146 size_t _free_chunks_total;
167 180
168 // add or delete (return) a chunk to the global freelist. 181 // add or delete (return) a chunk to the global freelist.
169 Metachunk* chunk_freelist_allocate(size_t word_size); 182 Metachunk* chunk_freelist_allocate(size_t word_size);
170 void chunk_freelist_deallocate(Metachunk* chunk); 183 void chunk_freelist_deallocate(Metachunk* chunk);
171 184
185 // Map a size to a list index assuming that there are lists
186 // for special, small, medium, and humongous chunks.
187 static ChunkIndex list_index(size_t size);
188
172 // Total of the space in the free chunks list 189 // Total of the space in the free chunks list
173 size_t free_chunks_total(); 190 size_t free_chunks_total();
174 size_t free_chunks_total_in_bytes(); 191 size_t free_chunks_total_in_bytes();
175 192
176 // Number of chunks in the free chunks list 193 // Number of chunks in the free chunks list
178 195
179 void inc_free_chunks_total(size_t v, size_t count = 1) { 196 void inc_free_chunks_total(size_t v, size_t count = 1) {
180 Atomic::add_ptr(count, &_free_chunks_count); 197 Atomic::add_ptr(count, &_free_chunks_count);
181 Atomic::add_ptr(v, &_free_chunks_total); 198 Atomic::add_ptr(v, &_free_chunks_total);
182 } 199 }
183 ChunkList* free_medium_chunks() { return &_free_chunks[1]; }
184 ChunkList* free_small_chunks() { return &_free_chunks[0]; }
185 ChunkTreeDictionary* humongous_dictionary() { 200 ChunkTreeDictionary* humongous_dictionary() {
186 return &_humongous_dictionary; 201 return &_humongous_dictionary;
187 } 202 }
188 203
189 ChunkList* free_chunks(ChunkIndex index); 204 ChunkList* free_chunks(ChunkIndex index);
398 413
399 public: 414 public:
400 VirtualSpaceList(size_t word_size); 415 VirtualSpaceList(size_t word_size);
401 VirtualSpaceList(ReservedSpace rs); 416 VirtualSpaceList(ReservedSpace rs);
402 417
403 Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); 418 Metachunk* get_new_chunk(size_t word_size,
419 size_t grow_chunks_by_words,
420 size_t medium_chunk_bunch);
421
422 // Get the first chunk for a Metaspace. Used for
423 // special cases such as the boot class loader, reflection
424 // class loader and anonymous class loader.
425 Metachunk* get_initialization_chunk(size_t word_size, size_t chunk_bunch);
404 426
405 VirtualSpaceNode* current_virtual_space() { 427 VirtualSpaceNode* current_virtual_space() {
406 return _current_virtual_space; 428 return _current_virtual_space;
407 } 429 }
408 430
499 class SpaceManager : public CHeapObj<mtClass> { 521 class SpaceManager : public CHeapObj<mtClass> {
500 friend class Metaspace; 522 friend class Metaspace;
501 friend class Metadebug; 523 friend class Metadebug;
502 524
503 private: 525 private:
526
504 // protects allocations and contains. 527 // protects allocations and contains.
505 Mutex* const _lock; 528 Mutex* const _lock;
529
530 // Chunk related size
531 size_t _medium_chunk_bunch;
506 532
507 // List of chunks in use by this SpaceManager. Allocations 533 // List of chunks in use by this SpaceManager. Allocations
508 // are done from the current chunk. The list is used for deallocating 534 // are done from the current chunk. The list is used for deallocating
509 // chunks when the SpaceManager is freed. 535 // chunks when the SpaceManager is freed.
510 Metachunk* _chunks_in_use[NumberOfInUseLists]; 536 Metachunk* _chunks_in_use[NumberOfInUseLists];
530 // protects virtualspace and chunk expansions 556 // protects virtualspace and chunk expansions
531 static const char* _expand_lock_name; 557 static const char* _expand_lock_name;
532 static const int _expand_lock_rank; 558 static const int _expand_lock_rank;
533 static Mutex* const _expand_lock; 559 static Mutex* const _expand_lock;
534 560
561 private:
535 // Accessors 562 // Accessors
536 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } 563 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; }
537 void set_chunks_in_use(ChunkIndex index, Metachunk* v) { _chunks_in_use[index] = v; } 564 void set_chunks_in_use(ChunkIndex index, Metachunk* v) { _chunks_in_use[index] = v; }
538 565
539 BlockFreelist* block_freelists() const { 566 BlockFreelist* block_freelists() const {
552 // Add chunk to the list of chunks in use 579 // Add chunk to the list of chunks in use
553 void add_chunk(Metachunk* v, bool make_current); 580 void add_chunk(Metachunk* v, bool make_current);
554 581
555 Mutex* lock() const { return _lock; } 582 Mutex* lock() const { return _lock; }
556 583
584 const char* chunk_size_name(ChunkIndex index) const;
585
586 protected:
587 void initialize();
588
557 public: 589 public:
558 SpaceManager(Mutex* lock, VirtualSpaceList* vs_list); 590 SpaceManager(Mutex* lock,
591 VirtualSpaceList* vs_list);
559 ~SpaceManager(); 592 ~SpaceManager();
560 593
561 enum ChunkSizes { // in words. 594 enum ChunkMultiples {
562 SmallChunk = 512, 595 MediumChunkMultiple = 4
563 MediumChunk = 8 * K,
564 MediumChunkBunch = 4 * MediumChunk
565 }; 596 };
566 597
567 // Accessors 598 // Accessors
599 size_t specialized_chunk_size() { return SpecializedChunk; }
600 size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; }
601 size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; }
602 size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; }
603
568 size_t allocation_total() const { return _allocation_total; } 604 size_t allocation_total() const { return _allocation_total; }
569 void inc_allocation_total(size_t v) { Atomic::add_ptr(v, &_allocation_total); } 605 void inc_allocation_total(size_t v) { Atomic::add_ptr(v, &_allocation_total); }
570 static bool is_humongous(size_t word_size) { return word_size > MediumChunk; } 606 bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
571 607
572 static Mutex* expand_lock() { return _expand_lock; } 608 static Mutex* expand_lock() { return _expand_lock; }
609
610 // Set the sizes for the initial chunks.
611 void get_initial_chunk_sizes(Metaspace::MetaspaceType type,
612 size_t* chunk_word_size,
613 size_t* class_chunk_word_size);
573 614
574 size_t sum_capacity_in_chunks_in_use() const; 615 size_t sum_capacity_in_chunks_in_use() const;
575 size_t sum_used_in_chunks_in_use() const; 616 size_t sum_used_in_chunks_in_use() const;
576 size_t sum_free_in_chunks_in_use() const; 617 size_t sum_free_in_chunks_in_use() const;
577 size_t sum_waste_in_chunks_in_use() const; 618 size_t sum_waste_in_chunks_in_use() const;
578 size_t sum_waste_in_chunks_in_use(ChunkIndex index ) const; 619 size_t sum_waste_in_chunks_in_use(ChunkIndex index ) const;
579 620
580 size_t sum_count_in_chunks_in_use(); 621 size_t sum_count_in_chunks_in_use();
581 size_t sum_count_in_chunks_in_use(ChunkIndex i); 622 size_t sum_count_in_chunks_in_use(ChunkIndex i);
623
624 Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words);
582 625
583 // Block allocation and deallocation. 626 // Block allocation and deallocation.
584 // Allocates a block from the current chunk 627 // Allocates a block from the current chunk
585 MetaWord* allocate(size_t word_size); 628 MetaWord* allocate(size_t word_size);
586 629
770 813
771 if (!_rs.is_reserved()) { 814 if (!_rs.is_reserved()) {
772 return false; 815 return false;
773 } 816 }
774 817
775 // Commit only 1 page instead of the whole reserved space _rs.size() 818 // An allocation out of this Virtualspace that is larger
776 size_t committed_byte_size = os::vm_page_size(); 819 // than an initial commit size can waste that initial committed
820 // space.
821 size_t committed_byte_size = 0;
777 bool result = virtual_space()->initialize(_rs, committed_byte_size); 822 bool result = virtual_space()->initialize(_rs, committed_byte_size);
778 if (result) { 823 if (result) {
779 set_top((MetaWord*)virtual_space()->low()); 824 set_top((MetaWord*)virtual_space()->low());
780 set_reserved(MemRegion((HeapWord*)_rs.base(), 825 set_reserved(MemRegion((HeapWord*)_rs.base(),
781 (HeapWord*)(_rs.base() + _rs.size()))); 826 (HeapWord*)(_rs.base() + _rs.size())));
797 size_t capacity = capacity_words_in_vs(); 842 size_t capacity = capacity_words_in_vs();
798 VirtualSpace* vs = virtual_space(); 843 VirtualSpace* vs = virtual_space();
799 st->print_cr(" space @ " PTR_FORMAT " " SIZE_FORMAT "K, %3d%% used " 844 st->print_cr(" space @ " PTR_FORMAT " " SIZE_FORMAT "K, %3d%% used "
800 "[" PTR_FORMAT ", " PTR_FORMAT ", " 845 "[" PTR_FORMAT ", " PTR_FORMAT ", "
801 PTR_FORMAT ", " PTR_FORMAT ")", 846 PTR_FORMAT ", " PTR_FORMAT ")",
802 vs, capacity / K, used * 100 / capacity, 847 vs, capacity / K,
848 capacity == 0 ? 0 : used * 100 / capacity,
803 bottom(), top(), end(), 849 bottom(), top(), end(),
804 vs->high_boundary()); 850 vs->high_boundary());
805 } 851 }
806 852
807 #ifdef ASSERT 853 #ifdef ASSERT
920 vsl->print_on(tty); 966 vsl->print_on(tty);
921 } 967 }
922 } 968 }
923 969
924 Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, 970 Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
925 size_t grow_chunks_by_words) { 971 size_t grow_chunks_by_words,
972 size_t medium_chunk_bunch) {
926 973
927 // Get a chunk from the chunk freelist 974 // Get a chunk from the chunk freelist
928 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); 975 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words);
929 976
930 // Allocate a chunk out of the current virtual space. 977 // Allocate a chunk out of the current virtual space.
933 } 980 }
934 981
935 if (next == NULL) { 982 if (next == NULL) {
936 // Not enough room in current virtual space. Try to commit 983 // Not enough room in current virtual space. Try to commit
937 // more space. 984 // more space.
938 size_t expand_vs_by_words = MAX2((size_t)SpaceManager::MediumChunkBunch, 985 size_t expand_vs_by_words = MAX2(medium_chunk_bunch,
939 grow_chunks_by_words); 986 grow_chunks_by_words);
940 size_t page_size_words = os::vm_page_size() / BytesPerWord; 987 size_t page_size_words = os::vm_page_size() / BytesPerWord;
941 size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words, 988 size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words,
942 page_size_words); 989 page_size_words);
943 bool vs_expanded = 990 bool vs_expanded =
944 current_virtual_space()->expand_by(aligned_expand_vs_by_words, false); 991 current_virtual_space()->expand_by(aligned_expand_vs_by_words, false);
952 MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words); 999 MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words);
953 if (grow_vs(grow_vs_words)) { 1000 if (grow_vs(grow_vs_words)) {
954 // Got it. It's on the list now. Get a chunk from it. 1001 // Got it. It's on the list now. Get a chunk from it.
955 next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words); 1002 next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words);
956 } 1003 }
957 if (TraceMetadataHumongousAllocation && SpaceManager::is_humongous(word_size)) {
958 gclog_or_tty->print_cr(" aligned_expand_vs_by_words " PTR_FORMAT,
959 aligned_expand_vs_by_words);
960 gclog_or_tty->print_cr(" grow_vs_words " PTR_FORMAT,
961 grow_vs_words);
962 }
963 } else { 1004 } else {
964 // Allocation will fail and induce a GC 1005 // Allocation will fail and induce a GC
965 if (TraceMetadataChunkAllocation && Verbose) { 1006 if (TraceMetadataChunkAllocation && Verbose) {
966 gclog_or_tty->print_cr("VirtualSpaceList::get_new_chunk():" 1007 gclog_or_tty->print_cr("VirtualSpaceList::get_new_chunk():"
967 " Fail instead of expand the metaspace"); 1008 " Fail instead of expand the metaspace");
972 next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); 1013 next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
973 assert(next != NULL, "Just expanded, should succeed"); 1014 assert(next != NULL, "Just expanded, should succeed");
974 } 1015 }
975 } 1016 }
976 1017
1018 assert(next == NULL || (next->next() == NULL && next->prev() == NULL),
1019 "New chunk is still on some list");
977 return next; 1020 return next;
1021 }
1022
1023 Metachunk* VirtualSpaceList::get_initialization_chunk(size_t chunk_word_size,
1024 size_t chunk_bunch) {
1025 // Get a chunk from the chunk freelist
1026 Metachunk* new_chunk = get_new_chunk(chunk_word_size,
1027 chunk_word_size,
1028 chunk_bunch);
1029 return new_chunk;
978 } 1030 }
979 1031
980 void VirtualSpaceList::print_on(outputStream* st) const { 1032 void VirtualSpaceList::print_on(outputStream* st) const {
981 if (TraceMetadataChunkAllocation && Verbose) { 1033 if (TraceMetadataChunkAllocation && Verbose) {
982 VirtualSpaceListIterator iter(virtual_space_list()); 1034 VirtualSpaceListIterator iter(virtual_space_list());
1371 return result; 1423 return result;
1372 } 1424 }
1373 1425
1374 void ChunkList::add_at_head(Metachunk* head, Metachunk* tail) { 1426 void ChunkList::add_at_head(Metachunk* head, Metachunk* tail) {
1375 assert_lock_strong(SpaceManager::expand_lock()); 1427 assert_lock_strong(SpaceManager::expand_lock());
1376 assert(tail->next() == NULL, "Not the tail"); 1428 assert(head == tail || tail->next() == NULL,
1429 "Not the tail or the head has already been added to a list");
1377 1430
1378 if (TraceMetadataChunkAllocation && Verbose) { 1431 if (TraceMetadataChunkAllocation && Verbose) {
1379 tty->print("ChunkList::add_at_head: "); 1432 gclog_or_tty->print("ChunkList::add_at_head(head, tail): ");
1380 Metachunk* cur = head; 1433 Metachunk* cur = head;
1381 while (cur != NULL) { 1434 while (cur != NULL) {
1382 tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size()); 1435 gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size());
1383 cur = cur->next(); 1436 cur = cur->next();
1384 } 1437 }
1385 tty->print_cr(""); 1438 gclog_or_tty->print_cr("");
1386 } 1439 }
1387 1440
1388 if (tail != NULL) { 1441 if (tail != NULL) {
1389 tail->set_next(_head); 1442 tail->set_next(_head);
1390 } 1443 }
1484 locked_verify_free_chunks_total(); 1537 locked_verify_free_chunks_total();
1485 } 1538 }
1486 1539
1487 void ChunkManager::locked_print_free_chunks(outputStream* st) { 1540 void ChunkManager::locked_print_free_chunks(outputStream* st) {
1488 assert_lock_strong(SpaceManager::expand_lock()); 1541 assert_lock_strong(SpaceManager::expand_lock());
1489 st->print_cr("Free chunk total 0x%x count 0x%x", 1542 st->print_cr("Free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
1490 _free_chunks_total, _free_chunks_count); 1543 _free_chunks_total, _free_chunks_count);
1491 } 1544 }
1492 1545
1493 void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { 1546 void ChunkManager::locked_print_sum_free_chunks(outputStream* st) {
1494 assert_lock_strong(SpaceManager::expand_lock()); 1547 assert_lock_strong(SpaceManager::expand_lock());
1495 st->print_cr("Sum free chunk total 0x%x count 0x%x", 1548 st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
1496 sum_free_chunks(), sum_free_chunks_count()); 1549 sum_free_chunks(), sum_free_chunks_count());
1497 } 1550 }
1498 ChunkList* ChunkManager::free_chunks(ChunkIndex index) { 1551 ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
1499 return &_free_chunks[index]; 1552 return &_free_chunks[index];
1500 } 1553 }
1502 // These methods that sum the free chunk lists are used in printing 1555 // These methods that sum the free chunk lists are used in printing
1503 // methods that are used in product builds. 1556 // methods that are used in product builds.
1504 size_t ChunkManager::sum_free_chunks() { 1557 size_t ChunkManager::sum_free_chunks() {
1505 assert_lock_strong(SpaceManager::expand_lock()); 1558 assert_lock_strong(SpaceManager::expand_lock());
1506 size_t result = 0; 1559 size_t result = 0;
1507 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1560 for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
1508 ChunkList* list = free_chunks(i); 1561 ChunkList* list = free_chunks(i);
1509 1562
1510 if (list == NULL) { 1563 if (list == NULL) {
1511 continue; 1564 continue;
1512 } 1565 }
1518 } 1571 }
1519 1572
1520 size_t ChunkManager::sum_free_chunks_count() { 1573 size_t ChunkManager::sum_free_chunks_count() {
1521 assert_lock_strong(SpaceManager::expand_lock()); 1574 assert_lock_strong(SpaceManager::expand_lock());
1522 size_t count = 0; 1575 size_t count = 0;
1523 for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { 1576 for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
1524 ChunkList* list = free_chunks(i); 1577 ChunkList* list = free_chunks(i);
1525 if (list == NULL) { 1578 if (list == NULL) {
1526 continue; 1579 continue;
1527 } 1580 }
1528 count = count + list->sum_list_count(); 1581 count = count + list->sum_list_count();
1530 count = count + humongous_dictionary()->total_free_blocks(); 1583 count = count + humongous_dictionary()->total_free_blocks();
1531 return count; 1584 return count;
1532 } 1585 }
1533 1586
1534 ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) { 1587 ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) {
1535 switch (word_size) { 1588 ChunkIndex index = list_index(word_size);
1536 case SpaceManager::SmallChunk : 1589 assert(index < HumongousIndex, "No humongous list");
1537 return &_free_chunks[0]; 1590 return free_chunks(index);
1538 case SpaceManager::MediumChunk :
1539 return &_free_chunks[1];
1540 default:
1541 assert(word_size > SpaceManager::MediumChunk, "List inconsistency");
1542 return &_free_chunks[2];
1543 }
1544 } 1591 }
1545 1592
1546 void ChunkManager::free_chunks_put(Metachunk* chunk) { 1593 void ChunkManager::free_chunks_put(Metachunk* chunk) {
1547 assert_lock_strong(SpaceManager::expand_lock()); 1594 assert_lock_strong(SpaceManager::expand_lock());
1548 ChunkList* free_list = find_free_chunks_list(chunk->word_size()); 1595 ChunkList* free_list = find_free_chunks_list(chunk->word_size());
1572 assert_lock_strong(SpaceManager::expand_lock()); 1619 assert_lock_strong(SpaceManager::expand_lock());
1573 1620
1574 slow_locked_verify(); 1621 slow_locked_verify();
1575 1622
1576 Metachunk* chunk = NULL; 1623 Metachunk* chunk = NULL;
1577 if (!SpaceManager::is_humongous(word_size)) { 1624 if (list_index(word_size) != HumongousIndex) {
1578 ChunkList* free_list = find_free_chunks_list(word_size); 1625 ChunkList* free_list = find_free_chunks_list(word_size);
1579 assert(free_list != NULL, "Sanity check"); 1626 assert(free_list != NULL, "Sanity check");
1580 1627
1581 chunk = free_list->head(); 1628 chunk = free_list->head();
1582 debug_only(Metachunk* debug_head = chunk;) 1629 debug_only(Metachunk* debug_head = chunk;)
1585 return NULL; 1632 return NULL;
1586 } 1633 }
1587 1634
1588 // Remove the chunk as the head of the list. 1635 // Remove the chunk as the head of the list.
1589 free_list->set_head(chunk->next()); 1636 free_list->set_head(chunk->next());
1590 chunk->set_next(NULL); 1637
1591 // Chunk has been removed from the chunks free list. 1638 // Chunk is being removed from the chunks free list.
1592 dec_free_chunks_total(chunk->capacity_word_size()); 1639 dec_free_chunks_total(chunk->capacity_word_size());
1593 1640
1594 if (TraceMetadataChunkAllocation && Verbose) { 1641 if (TraceMetadataChunkAllocation && Verbose) {
1595 tty->print_cr("ChunkManager::free_chunks_get: free_list " 1642 tty->print_cr("ChunkManager::free_chunks_get: free_list "
1596 PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT, 1643 PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
1612 // Chunk is being removed from the chunks free list. 1659 // Chunk is being removed from the chunks free list.
1613 dec_free_chunks_total(chunk->capacity_word_size()); 1660 dec_free_chunks_total(chunk->capacity_word_size());
1614 #ifdef ASSERT 1661 #ifdef ASSERT
1615 chunk->set_is_free(false); 1662 chunk->set_is_free(false);
1616 #endif 1663 #endif
1617 } 1664 } else {
1618 } 1665 return NULL;
1666 }
1667 }
1668
1669 // Remove it from the links to this freelist
1670 chunk->set_next(NULL);
1671 chunk->set_prev(NULL);
1619 slow_locked_verify(); 1672 slow_locked_verify();
1620 return chunk; 1673 return chunk;
1621 } 1674 }
1622 1675
1623 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { 1676 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
1628 Metachunk* chunk = free_chunks_get(word_size); 1681 Metachunk* chunk = free_chunks_get(word_size);
1629 if (chunk == NULL) { 1682 if (chunk == NULL) {
1630 return NULL; 1683 return NULL;
1631 } 1684 }
1632 1685
1633 assert(word_size <= chunk->word_size() || 1686 assert((word_size <= chunk->word_size()) ||
1634 SpaceManager::is_humongous(chunk->word_size()), 1687 list_index(chunk->word_size() == HumongousIndex),
1635 "Non-humongous variable sized chunk"); 1688 "Non-humongous variable sized chunk");
1636 if (TraceMetadataChunkAllocation) { 1689 if (TraceMetadataChunkAllocation) {
1637 tty->print("ChunkManager::chunk_freelist_allocate: chunk " 1690 size_t list_count;
1638 PTR_FORMAT " size " SIZE_FORMAT " ", 1691 if (list_index(word_size) < HumongousIndex) {
1639 chunk, chunk->word_size()); 1692 ChunkList* list = find_free_chunks_list(word_size);
1693 list_count = list->sum_list_count();
1694 } else {
1695 list_count = humongous_dictionary()->total_count();
1696 }
1697 tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
1698 PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ",
1699 this, chunk, chunk->word_size(), list_count);
1640 locked_print_free_chunks(tty); 1700 locked_print_free_chunks(tty);
1641 } 1701 }
1642 1702
1643 return chunk; 1703 return chunk;
1644 } 1704 }
1649 } 1709 }
1650 } 1710 }
1651 1711
1652 // SpaceManager methods 1712 // SpaceManager methods
1653 1713
1714 void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type,
1715 size_t* chunk_word_size,
1716 size_t* class_chunk_word_size) {
1717 switch (type) {
1718 case Metaspace::BootMetaspaceType:
1719 *chunk_word_size = Metaspace::first_chunk_word_size();
1720 *class_chunk_word_size = Metaspace::first_class_chunk_word_size();
1721 break;
1722 case Metaspace::ROMetaspaceType:
1723 *chunk_word_size = SharedReadOnlySize / wordSize;
1724 *class_chunk_word_size = ClassSpecializedChunk;
1725 break;
1726 case Metaspace::ReadWriteMetaspaceType:
1727 *chunk_word_size = SharedReadWriteSize / wordSize;
1728 *class_chunk_word_size = ClassSpecializedChunk;
1729 break;
1730 case Metaspace::AnonymousMetaspaceType:
1731 case Metaspace::ReflectionMetaspaceType:
1732 *chunk_word_size = SpecializedChunk;
1733 *class_chunk_word_size = ClassSpecializedChunk;
1734 break;
1735 default:
1736 *chunk_word_size = SmallChunk;
1737 *class_chunk_word_size = ClassSmallChunk;
1738 break;
1739 }
1740 assert(chunk_word_size != 0 && class_chunk_word_size != 0,
1741 err_msg("Initial chunks sizes bad: data " SIZE_FORMAT
1742 " class " SIZE_FORMAT,
1743 chunk_word_size, class_chunk_word_size));
1744 }
1745
1654 size_t SpaceManager::sum_free_in_chunks_in_use() const { 1746 size_t SpaceManager::sum_free_in_chunks_in_use() const {
1655 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1747 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1656 size_t free = 0; 1748 size_t free = 0;
1657 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 1749 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1658 Metachunk* chunk = chunks_in_use(i); 1750 Metachunk* chunk = chunks_in_use(i);
1659 while (chunk != NULL) { 1751 while (chunk != NULL) {
1660 free += chunk->free_word_size(); 1752 free += chunk->free_word_size();
1661 chunk = chunk->next(); 1753 chunk = chunk->next();
1662 } 1754 }
1665 } 1757 }
1666 1758
1667 size_t SpaceManager::sum_waste_in_chunks_in_use() const { 1759 size_t SpaceManager::sum_waste_in_chunks_in_use() const {
1668 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1760 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1669 size_t result = 0; 1761 size_t result = 0;
1670 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 1762 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1671
1672
1673 result += sum_waste_in_chunks_in_use(i); 1763 result += sum_waste_in_chunks_in_use(i);
1674 } 1764 }
1675 1765
1676 return result; 1766 return result;
1677 } 1767 }
1678 1768
1679 size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { 1769 size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const {
1680 size_t result = 0; 1770 size_t result = 0;
1681 size_t count = 0;
1682 Metachunk* chunk = chunks_in_use(index); 1771 Metachunk* chunk = chunks_in_use(index);
1683 // Count the free space in all the chunk but not the 1772 // Count the free space in all the chunk but not the
1684 // current chunk from which allocations are still being done. 1773 // current chunk from which allocations are still being done.
1685 if (chunk != NULL) { 1774 if (chunk != NULL) {
1686 Metachunk* prev = chunk; 1775 Metachunk* prev = chunk;
1687 while (chunk != NULL && chunk != current_chunk()) { 1776 while (chunk != NULL && chunk != current_chunk()) {
1688 result += chunk->free_word_size(); 1777 result += chunk->free_word_size();
1689 prev = chunk; 1778 prev = chunk;
1690 chunk = chunk->next(); 1779 chunk = chunk->next();
1691 count++;
1692 } 1780 }
1693 } 1781 }
1694 return result; 1782 return result;
1695 } 1783 }
1696 1784
1697 size_t SpaceManager::sum_capacity_in_chunks_in_use() const { 1785 size_t SpaceManager::sum_capacity_in_chunks_in_use() const {
1698 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1786 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1699 size_t sum = 0; 1787 size_t sum = 0;
1700 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 1788 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1701 Metachunk* chunk = chunks_in_use(i); 1789 Metachunk* chunk = chunks_in_use(i);
1702 while (chunk != NULL) { 1790 while (chunk != NULL) {
1703 // Just changed this sum += chunk->capacity_word_size(); 1791 // Just changed this sum += chunk->capacity_word_size();
1704 // sum += chunk->word_size() - Metachunk::overhead(); 1792 // sum += chunk->word_size() - Metachunk::overhead();
1705 sum += chunk->capacity_word_size(); 1793 sum += chunk->capacity_word_size();
1709 return sum; 1797 return sum;
1710 } 1798 }
1711 1799
1712 size_t SpaceManager::sum_count_in_chunks_in_use() { 1800 size_t SpaceManager::sum_count_in_chunks_in_use() {
1713 size_t count = 0; 1801 size_t count = 0;
1714 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 1802 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1715 count = count + sum_count_in_chunks_in_use(i); 1803 count = count + sum_count_in_chunks_in_use(i);
1716 } 1804 }
1717 1805
1718 return count; 1806 return count;
1719 } 1807 }
1730 1818
1731 1819
1732 size_t SpaceManager::sum_used_in_chunks_in_use() const { 1820 size_t SpaceManager::sum_used_in_chunks_in_use() const {
1733 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1821 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1734 size_t used = 0; 1822 size_t used = 0;
1735 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 1823 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1736 Metachunk* chunk = chunks_in_use(i); 1824 Metachunk* chunk = chunks_in_use(i);
1737 while (chunk != NULL) { 1825 while (chunk != NULL) {
1738 used += chunk->used_word_size(); 1826 used += chunk->used_word_size();
1739 chunk = chunk->next(); 1827 chunk = chunk->next();
1740 } 1828 }
1742 return used; 1830 return used;
1743 } 1831 }
1744 1832
1745 void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { 1833 void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const {
1746 1834
1747 Metachunk* small_chunk = chunks_in_use(SmallIndex); 1835 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1748 st->print_cr("SpaceManager: small chunk " PTR_FORMAT 1836 Metachunk* chunk = chunks_in_use(i);
1749 " free " SIZE_FORMAT, 1837 st->print("SpaceManager: %s " PTR_FORMAT,
1750 small_chunk, 1838 chunk_size_name(i), chunk);
1751 small_chunk->free_word_size()); 1839 if (chunk != NULL) {
1752 1840 st->print_cr(" free " SIZE_FORMAT,
1753 Metachunk* medium_chunk = chunks_in_use(MediumIndex); 1841 chunk->free_word_size());
1754 st->print("medium chunk " PTR_FORMAT, medium_chunk); 1842 } else {
1755 Metachunk* tail = current_chunk(); 1843 st->print_cr("");
1756 st->print_cr(" current chunk " PTR_FORMAT, tail); 1844 }
1757 1845 }
1758 Metachunk* head = chunks_in_use(HumongousIndex);
1759 st->print_cr("humongous chunk " PTR_FORMAT, head);
1760 1846
1761 vs_list()->chunk_manager()->locked_print_free_chunks(st); 1847 vs_list()->chunk_manager()->locked_print_free_chunks(st);
1762 vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); 1848 vs_list()->chunk_manager()->locked_print_sum_free_chunks(st);
1763 } 1849 }
1764 1850
1770 // chunks will be allocated. 1856 // chunks will be allocated.
1771 size_t chunk_word_size; 1857 size_t chunk_word_size;
1772 if (chunks_in_use(MediumIndex) == NULL && 1858 if (chunks_in_use(MediumIndex) == NULL &&
1773 (!has_small_chunk_limit() || 1859 (!has_small_chunk_limit() ||
1774 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) { 1860 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) {
1775 chunk_word_size = (size_t) SpaceManager::SmallChunk; 1861 chunk_word_size = (size_t) small_chunk_size();
1776 if (word_size + Metachunk::overhead() > SpaceManager::SmallChunk) { 1862 if (word_size + Metachunk::overhead() > small_chunk_size()) {
1777 chunk_word_size = MediumChunk; 1863 chunk_word_size = medium_chunk_size();
1778 } 1864 }
1779 } else { 1865 } else {
1780 chunk_word_size = MediumChunk; 1866 chunk_word_size = medium_chunk_size();
1781 } 1867 }
1782 1868
1783 // Might still need a humongous chunk 1869 // Might still need a humongous chunk. Enforce an
1870 // eight word granularity to facilitate reuse (some
1871 // wastage but better chance of reuse).
1872 size_t if_humongous_sized_chunk =
1873 align_size_up(word_size + Metachunk::overhead(),
1874 HumongousChunkGranularity);
1784 chunk_word_size = 1875 chunk_word_size =
1785 MAX2((size_t) chunk_word_size, word_size + Metachunk::overhead()); 1876 MAX2((size_t) chunk_word_size, if_humongous_sized_chunk);
1786 1877
1878 assert(!SpaceManager::is_humongous(word_size) ||
1879 chunk_word_size == if_humongous_sized_chunk,
1880 err_msg("Size calculation is wrong, word_size " SIZE_FORMAT
1881 " chunk_word_size " SIZE_FORMAT,
1882 word_size, chunk_word_size));
1787 if (TraceMetadataHumongousAllocation && 1883 if (TraceMetadataHumongousAllocation &&
1788 SpaceManager::is_humongous(word_size)) { 1884 SpaceManager::is_humongous(word_size)) {
1789 gclog_or_tty->print_cr("Metadata humongous allocation:"); 1885 gclog_or_tty->print_cr("Metadata humongous allocation:");
1790 gclog_or_tty->print_cr(" word_size " PTR_FORMAT, word_size); 1886 gclog_or_tty->print_cr(" word_size " PTR_FORMAT, word_size);
1791 gclog_or_tty->print_cr(" chunk_word_size " PTR_FORMAT, 1887 gclog_or_tty->print_cr(" chunk_word_size " PTR_FORMAT,
1803 current_chunk()->allocate(word_size) == NULL, 1899 current_chunk()->allocate(word_size) == NULL,
1804 "Don't need to expand"); 1900 "Don't need to expand");
1805 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); 1901 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
1806 1902
1807 if (TraceMetadataChunkAllocation && Verbose) { 1903 if (TraceMetadataChunkAllocation && Verbose) {
1904 size_t words_left = 0;
1905 size_t words_used = 0;
1906 if (current_chunk() != NULL) {
1907 words_left = current_chunk()->free_word_size();
1908 words_used = current_chunk()->used_word_size();
1909 }
1808 gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT 1910 gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT
1809 " words " SIZE_FORMAT " space left", 1911 " words " SIZE_FORMAT " words used " SIZE_FORMAT
1810 word_size, current_chunk() != NULL ? 1912 " words left",
1811 current_chunk()->free_word_size() : 0); 1913 word_size, words_used, words_left);
1812 } 1914 }
1813 1915
1814 // Get another chunk out of the virtual space 1916 // Get another chunk out of the virtual space
1815 size_t grow_chunks_by_words = calc_chunk_size(word_size); 1917 size_t grow_chunks_by_words = calc_chunk_size(word_size);
1816 Metachunk* next = vs_list()->get_new_chunk(word_size, grow_chunks_by_words); 1918 Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
1817 1919
1818 // If a chunk was available, add it to the in-use chunk list 1920 // If a chunk was available, add it to the in-use chunk list
1819 // and do an allocation from it. 1921 // and do an allocation from it.
1820 if (next != NULL) { 1922 if (next != NULL) {
1821 Metadebug::deallocate_chunk_a_lot(this, grow_chunks_by_words); 1923 Metadebug::deallocate_chunk_a_lot(this, grow_chunks_by_words);
1826 return NULL; 1928 return NULL;
1827 } 1929 }
1828 1930
1829 void SpaceManager::print_on(outputStream* st) const { 1931 void SpaceManager::print_on(outputStream* st) const {
1830 1932
1831 for (ChunkIndex i = SmallIndex; 1933 for (ChunkIndex i = ZeroIndex;
1832 i < NumberOfInUseLists ; 1934 i < NumberOfInUseLists ;
1833 i = next_chunk_index(i) ) { 1935 i = next_chunk_index(i) ) {
1834 st->print_cr(" chunks_in_use " PTR_FORMAT " chunk size " PTR_FORMAT, 1936 st->print_cr(" chunks_in_use " PTR_FORMAT " chunk size " PTR_FORMAT,
1835 chunks_in_use(i), 1937 chunks_in_use(i),
1836 chunks_in_use(i) == NULL ? 0 : chunks_in_use(i)->word_size()); 1938 chunks_in_use(i) == NULL ? 0 : chunks_in_use(i)->word_size());
1845 st->print_cr("total in block free lists " SIZE_FORMAT, 1947 st->print_cr("total in block free lists " SIZE_FORMAT,
1846 block_freelists()->total_size()); 1948 block_freelists()->total_size());
1847 } 1949 }
1848 } 1950 }
1849 1951
1850 SpaceManager::SpaceManager(Mutex* lock, VirtualSpaceList* vs_list) : 1952 SpaceManager::SpaceManager(Mutex* lock,
1953 VirtualSpaceList* vs_list) :
1851 _vs_list(vs_list), 1954 _vs_list(vs_list),
1852 _allocation_total(0), 1955 _allocation_total(0),
1853 _lock(lock) { 1956 _lock(lock)
1957 {
1958 initialize();
1959 }
1960
1961 void SpaceManager::initialize() {
1854 Metadebug::init_allocation_fail_alot_count(); 1962 Metadebug::init_allocation_fail_alot_count();
1855 for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 1963 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1856 _chunks_in_use[i] = NULL; 1964 _chunks_in_use[i] = NULL;
1857 } 1965 }
1858 _current_chunk = NULL; 1966 _current_chunk = NULL;
1859 if (TraceMetadataChunkAllocation && Verbose) { 1967 if (TraceMetadataChunkAllocation && Verbose) {
1860 gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, this); 1968 gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, this);
1883 sum_count_in_chunks_in_use()); 1991 sum_count_in_chunks_in_use());
1884 1992
1885 // Add all the chunks in use by this space manager 1993 // Add all the chunks in use by this space manager
1886 // to the global list of free chunks. 1994 // to the global list of free chunks.
1887 1995
1888 // Small chunks. There is one _current_chunk for each 1996 // Follow each list of chunks-in-use and add them to the
1889 // Metaspace. It could point to a small or medium chunk. 1997 // free lists. Each list is NULL terminated.
1890 // Rather than determine which it is, follow the list of 1998
1891 // small chunks to add them to the free list 1999 for (ChunkIndex i = ZeroIndex; i < HumongousIndex; i = next_chunk_index(i)) {
1892 Metachunk* small_chunk = chunks_in_use(SmallIndex); 2000 if (TraceMetadataChunkAllocation && Verbose) {
1893 chunk_manager->free_small_chunks()->add_at_head(small_chunk); 2001 gclog_or_tty->print_cr("returned %d %s chunks to freelist",
1894 set_chunks_in_use(SmallIndex, NULL); 2002 sum_count_in_chunks_in_use(i),
1895 2003 chunk_size_name(i));
1896 // After the small chunk are the medium chunks 2004 }
1897 Metachunk* medium_chunk = chunks_in_use(MediumIndex); 2005 Metachunk* chunks = chunks_in_use(i);
1898 assert(medium_chunk == NULL || 2006 chunk_manager->free_chunks(i)->add_at_head(chunks);
1899 medium_chunk->word_size() == MediumChunk, 2007 set_chunks_in_use(i, NULL);
1900 "Chunk is on the wrong list"); 2008 if (TraceMetadataChunkAllocation && Verbose) {
1901 2009 gclog_or_tty->print_cr("updated freelist count %d %s",
1902 if (medium_chunk != NULL) { 2010 chunk_manager->free_chunks(i)->sum_list_count(),
1903 Metachunk* head = medium_chunk; 2011 chunk_size_name(i));
1904 // If there is a medium chunk then the _current_chunk can only 2012 }
1905 // point to the last medium chunk. 2013 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
1906 Metachunk* tail = current_chunk(); 2014 }
1907 chunk_manager->free_medium_chunks()->add_at_head(head, tail); 2015
1908 set_chunks_in_use(MediumIndex, NULL); 2016 // The medium chunk case may be optimized by passing the head and
1909 } 2017 // tail of the medium chunk list to add_at_head(). The tail is often
2018 // the current chunk but there are probably exceptions.
1910 2019
1911 // Humongous chunks 2020 // Humongous chunks
2021 if (TraceMetadataChunkAllocation && Verbose) {
2022 gclog_or_tty->print_cr("returned %d %s humongous chunks to dictionary",
2023 sum_count_in_chunks_in_use(HumongousIndex),
2024 chunk_size_name(HumongousIndex));
2025 gclog_or_tty->print("Humongous chunk dictionary: ");
2026 }
1912 // Humongous chunks are never the current chunk. 2027 // Humongous chunks are never the current chunk.
1913 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); 2028 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
1914 2029
1915 while (humongous_chunks != NULL) { 2030 while (humongous_chunks != NULL) {
1916 #ifdef ASSERT 2031 #ifdef ASSERT
1917 humongous_chunks->set_is_free(true); 2032 humongous_chunks->set_is_free(true);
1918 #endif 2033 #endif
2034 if (TraceMetadataChunkAllocation && Verbose) {
2035 gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ",
2036 humongous_chunks,
2037 humongous_chunks->word_size());
2038 }
2039 assert(humongous_chunks->word_size() == (size_t)
2040 align_size_up(humongous_chunks->word_size(),
2041 HumongousChunkGranularity),
2042 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT
2043 " granularity " SIZE_FORMAT,
2044 humongous_chunks->word_size(), HumongousChunkGranularity));
1919 Metachunk* next_humongous_chunks = humongous_chunks->next(); 2045 Metachunk* next_humongous_chunks = humongous_chunks->next();
1920 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); 2046 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks);
1921 humongous_chunks = next_humongous_chunks; 2047 humongous_chunks = next_humongous_chunks;
1922 } 2048 }
2049 if (TraceMetadataChunkAllocation && Verbose) {
2050 gclog_or_tty->print_cr("");
2051 gclog_or_tty->print_cr("updated dictionary count %d %s",
2052 chunk_manager->humongous_dictionary()->total_count(),
2053 chunk_size_name(HumongousIndex));
2054 }
1923 set_chunks_in_use(HumongousIndex, NULL); 2055 set_chunks_in_use(HumongousIndex, NULL);
1924 chunk_manager->slow_locked_verify(); 2056 chunk_manager->slow_locked_verify();
2057 }
2058
2059 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
2060 switch (index) {
2061 case SpecializedIndex:
2062 return "Specialized";
2063 case SmallIndex:
2064 return "Small";
2065 case MediumIndex:
2066 return "Medium";
2067 case HumongousIndex:
2068 return "Humongous";
2069 default:
2070 return NULL;
2071 }
2072 }
2073
2074 ChunkIndex ChunkManager::list_index(size_t size) {
2075 switch (size) {
2076 case SpecializedChunk:
2077 assert(SpecializedChunk == ClassSpecializedChunk,
2078 "Need branch for ClassSpecializedChunk");
2079 return SpecializedIndex;
2080 case SmallChunk:
2081 case ClassSmallChunk:
2082 return SmallIndex;
2083 case MediumChunk:
2084 case ClassMediumChunk:
2085 return MediumIndex;
2086 default:
2087 assert(size > MediumChunk && size > ClassMediumChunk,
2088 "Not a humongous chunk");
2089 return HumongousIndex;
2090 }
1925 } 2091 }
1926 2092
1927 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { 2093 void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
1928 assert_lock_strong(_lock); 2094 assert_lock_strong(_lock);
1929 size_t min_size = TreeChunk<Metablock, FreeList>::min_size(); 2095 size_t min_size = TreeChunk<Metablock, FreeList>::min_size();
1940 2106
1941 new_chunk->reset_empty(); 2107 new_chunk->reset_empty();
1942 2108
1943 // Find the correct list and and set the current 2109 // Find the correct list and and set the current
1944 // chunk for that list. 2110 // chunk for that list.
1945 switch (new_chunk->word_size()) { 2111 ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
1946 case SpaceManager::SmallChunk : 2112
1947 if (chunks_in_use(SmallIndex) == NULL) { 2113 if (index != HumongousIndex) {
1948 // First chunk to add to the list
1949 set_chunks_in_use(SmallIndex, new_chunk);
1950 } else {
1951 assert(current_chunk()->word_size() == SpaceManager::SmallChunk,
1952 err_msg( "Incorrect mix of sizes in chunk list "
1953 SIZE_FORMAT " new chunk " SIZE_FORMAT,
1954 current_chunk()->word_size(), new_chunk->word_size()));
1955 current_chunk()->set_next(new_chunk);
1956 }
1957 // Make current chunk
1958 set_current_chunk(new_chunk); 2114 set_current_chunk(new_chunk);
1959 break; 2115 new_chunk->set_next(chunks_in_use(index));
1960 case SpaceManager::MediumChunk : 2116 set_chunks_in_use(index, new_chunk);
1961 if (chunks_in_use(MediumIndex) == NULL) { 2117 } else {
1962 // About to add the first medium chunk so teminate the
1963 // small chunk list. In general once medium chunks are
1964 // being added, we're past the need for small chunks.
1965 if (current_chunk() != NULL) {
1966 // Only a small chunk or the initial chunk could be
1967 // the current chunk if this is the first medium chunk.
1968 assert(current_chunk()->word_size() == SpaceManager::SmallChunk ||
1969 chunks_in_use(SmallIndex) == NULL,
1970 err_msg("Should be a small chunk or initial chunk, current chunk "
1971 SIZE_FORMAT " new chunk " SIZE_FORMAT,
1972 current_chunk()->word_size(), new_chunk->word_size()));
1973 current_chunk()->set_next(NULL);
1974 }
1975 // First chunk to add to the list
1976 set_chunks_in_use(MediumIndex, new_chunk);
1977
1978 } else {
1979 // As a minimum the first medium chunk added would
1980 // have become the _current_chunk
1981 // so the _current_chunk has to be non-NULL here
1982 // (although not necessarily still the first medium chunk).
1983 assert(current_chunk()->word_size() == SpaceManager::MediumChunk,
1984 "A medium chunk should the current chunk");
1985 current_chunk()->set_next(new_chunk);
1986 }
1987 // Make current chunk
1988 set_current_chunk(new_chunk);
1989 break;
1990 default: {
1991 // For null class loader data and DumpSharedSpaces, the first chunk isn't 2118 // For null class loader data and DumpSharedSpaces, the first chunk isn't
1992 // small, so small will be null. Link this first chunk as the current 2119 // small, so small will be null. Link this first chunk as the current
1993 // chunk. 2120 // chunk.
1994 if (make_current) { 2121 if (make_current) {
1995 // Set as the current chunk but otherwise treat as a humongous chunk. 2122 // Set as the current chunk but otherwise treat as a humongous chunk.
2002 new_chunk->set_next(chunks_in_use(HumongousIndex)); 2129 new_chunk->set_next(chunks_in_use(HumongousIndex));
2003 set_chunks_in_use(HumongousIndex, new_chunk); 2130 set_chunks_in_use(HumongousIndex, new_chunk);
2004 2131
2005 assert(new_chunk->word_size() > MediumChunk, "List inconsistency"); 2132 assert(new_chunk->word_size() > MediumChunk, "List inconsistency");
2006 } 2133 }
2007 }
2008 2134
2009 assert(new_chunk->is_empty(), "Not ready for reuse"); 2135 assert(new_chunk->is_empty(), "Not ready for reuse");
2010 if (TraceMetadataChunkAllocation && Verbose) { 2136 if (TraceMetadataChunkAllocation && Verbose) {
2011 gclog_or_tty->print("SpaceManager::add_chunk: %d) ", 2137 gclog_or_tty->print("SpaceManager::add_chunk: %d) ",
2012 sum_count_in_chunks_in_use()); 2138 sum_count_in_chunks_in_use());
2013 new_chunk->print_on(gclog_or_tty); 2139 new_chunk->print_on(gclog_or_tty);
2014 vs_list()->chunk_manager()->locked_print_free_chunks(tty); 2140 vs_list()->chunk_manager()->locked_print_free_chunks(tty);
2015 } 2141 }
2142 }
2143
2144 Metachunk* SpaceManager::get_new_chunk(size_t word_size,
2145 size_t grow_chunks_by_words) {
2146
2147 Metachunk* next = vs_list()->get_new_chunk(word_size,
2148 grow_chunks_by_words,
2149 medium_chunk_bunch());
2150
2151 if (TraceMetadataHumongousAllocation &&
2152 SpaceManager::is_humongous(next->word_size())) {
2153 gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT,
2154 next->word_size());
2155 }
2156
2157 return next;
2016 } 2158 }
2017 2159
2018 MetaWord* SpaceManager::allocate(size_t word_size) { 2160 MetaWord* SpaceManager::allocate(size_t word_size) {
2019 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 2161 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2020 2162
2088 void SpaceManager::verify() { 2230 void SpaceManager::verify() {
2089 // If there are blocks in the dictionary, then 2231 // If there are blocks in the dictionary, then
2090 // verfication of chunks does not work since 2232 // verfication of chunks does not work since
2091 // being in the dictionary alters a chunk. 2233 // being in the dictionary alters a chunk.
2092 if (block_freelists()->total_size() == 0) { 2234 if (block_freelists()->total_size() == 0) {
2093 // Skip the small chunks because their next link points to 2235 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2094 // medium chunks. This is because the small chunk is the
2095 // current chunk (for allocations) until it is full and the
2096 // the addition of the next chunk does not NULL the next
2097 // like of the small chunk.
2098 for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2099 Metachunk* curr = chunks_in_use(i); 2236 Metachunk* curr = chunks_in_use(i);
2100 while (curr != NULL) { 2237 while (curr != NULL) {
2101 curr->verify(); 2238 curr->verify();
2102 verify_chunk_size(curr); 2239 verify_chunk_size(curr);
2103 curr = curr->next(); 2240 curr = curr->next();
2106 } 2243 }
2107 } 2244 }
2108 2245
2109 void SpaceManager::verify_chunk_size(Metachunk* chunk) { 2246 void SpaceManager::verify_chunk_size(Metachunk* chunk) {
2110 assert(is_humongous(chunk->word_size()) || 2247 assert(is_humongous(chunk->word_size()) ||
2111 chunk->word_size() == MediumChunk || 2248 chunk->word_size() == medium_chunk_size() ||
2112 chunk->word_size() == SmallChunk, 2249 chunk->word_size() == small_chunk_size() ||
2250 chunk->word_size() == specialized_chunk_size(),
2113 "Chunk size is wrong"); 2251 "Chunk size is wrong");
2114 return; 2252 return;
2115 } 2253 }
2116 2254
2117 #ifdef ASSERT 2255 #ifdef ASSERT
2118 void SpaceManager::verify_allocation_total() { 2256 void SpaceManager::verify_allocation_total() {
2119 #if 0
2120 // Verification is only guaranteed at a safepoint. 2257 // Verification is only guaranteed at a safepoint.
2121 if (SafepointSynchronize::is_at_safepoint()) { 2258 if (SafepointSynchronize::is_at_safepoint()) {
2122 gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT 2259 gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT
2123 " sum_used_in_chunks_in_use " SIZE_FORMAT, 2260 " sum_used_in_chunks_in_use " SIZE_FORMAT,
2124 this, 2261 this,
2127 } 2264 }
2128 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 2265 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2129 assert(allocation_total() == sum_used_in_chunks_in_use(), 2266 assert(allocation_total() == sum_used_in_chunks_in_use(),
2130 err_msg("allocation total is not consistent %d vs %d", 2267 err_msg("allocation total is not consistent %d vs %d",
2131 allocation_total(), sum_used_in_chunks_in_use())); 2268 allocation_total(), sum_used_in_chunks_in_use()));
2132 #endif
2133 } 2269 }
2134 2270
2135 #endif 2271 #endif
2136 2272
2137 void SpaceManager::dump(outputStream* const out) const { 2273 void SpaceManager::dump(outputStream* const out) const {
2140 uint i = 0; 2276 uint i = 0;
2141 size_t used = 0; 2277 size_t used = 0;
2142 size_t capacity = 0; 2278 size_t capacity = 0;
2143 2279
2144 // Add up statistics for all chunks in this SpaceManager. 2280 // Add up statistics for all chunks in this SpaceManager.
2145 for (ChunkIndex index = SmallIndex; 2281 for (ChunkIndex index = ZeroIndex;
2146 index < NumberOfInUseLists; 2282 index < NumberOfInUseLists;
2147 index = next_chunk_index(index)) { 2283 index = next_chunk_index(index)) {
2148 for (Metachunk* curr = chunks_in_use(index); 2284 for (Metachunk* curr = chunks_in_use(index);
2149 curr != NULL; 2285 curr != NULL;
2150 curr = curr->next()) { 2286 curr = curr->next()) {
2158 capacity += curr->capacity_word_size(); 2294 capacity += curr->capacity_word_size();
2159 waste += curr->free_word_size() + curr->overhead();; 2295 waste += curr->free_word_size() + curr->overhead();;
2160 } 2296 }
2161 } 2297 }
2162 2298
2163 size_t free = current_chunk()->free_word_size(); 2299 size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size();
2164 // Free space isn't wasted. 2300 // Free space isn't wasted.
2165 waste -= free; 2301 waste -= free;
2166 2302
2167 out->print_cr("total of all chunks " SIZE_FORMAT " used " SIZE_FORMAT 2303 out->print_cr("total of all chunks " SIZE_FORMAT " used " SIZE_FORMAT
2168 " free " SIZE_FORMAT " capacity " SIZE_FORMAT 2304 " free " SIZE_FORMAT " capacity " SIZE_FORMAT
2169 " waste " SIZE_FORMAT, curr_total, used, free, capacity, waste); 2305 " waste " SIZE_FORMAT, curr_total, used, free, capacity, waste);
2170 } 2306 }
2171 2307
2172 #ifndef PRODUCT 2308 #ifndef PRODUCT
2173 void SpaceManager::mangle_freed_chunks() { 2309 void SpaceManager::mangle_freed_chunks() {
2174 for (ChunkIndex index = SmallIndex; 2310 for (ChunkIndex index = ZeroIndex;
2175 index < NumberOfInUseLists; 2311 index < NumberOfInUseLists;
2176 index = next_chunk_index(index)) { 2312 index = next_chunk_index(index)) {
2177 for (Metachunk* curr = chunks_in_use(index); 2313 for (Metachunk* curr = chunks_in_use(index);
2178 curr != NULL; 2314 curr != NULL;
2179 curr = curr->next()) { 2315 curr = curr->next()) {
2180 // Try to detect incorrectly terminated small chunk
2181 // list.
2182 assert(index == MediumIndex || curr != chunks_in_use(MediumIndex),
2183 err_msg("Mangling medium chunks in small chunks? "
2184 "curr " PTR_FORMAT " medium list " PTR_FORMAT,
2185 curr, chunks_in_use(MediumIndex)));
2186 curr->mangle(); 2316 curr->mangle();
2187 } 2317 }
2188 } 2318 }
2189 } 2319 }
2190 #endif // PRODUCT 2320 #endif // PRODUCT
2191
2192 2321
2193 // MetaspaceAux 2322 // MetaspaceAux
2194 2323
2195 size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) { 2324 size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) {
2196 size_t used = 0; 2325 size_t used = 0;
2234 Metaspace::class_space_list()->virtual_space_total() : 2363 Metaspace::class_space_list()->virtual_space_total() :
2235 Metaspace::space_list()->virtual_space_total(); 2364 Metaspace::space_list()->virtual_space_total();
2236 return reserved * BytesPerWord; 2365 return reserved * BytesPerWord;
2237 } 2366 }
2238 2367
2239 size_t MetaspaceAux::min_chunk_size() { return SpaceManager::MediumChunk; } 2368 size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); }
2240 2369
2241 size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { 2370 size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) {
2242 ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? 2371 ChunkManager* chunk = (mdtype == Metaspace::ClassType) ?
2243 Metaspace::class_space_list()->chunk_manager() : 2372 Metaspace::class_space_list()->chunk_manager() :
2244 Metaspace::space_list()->chunk_manager(); 2373 Metaspace::space_list()->chunk_manager();
2314 } 2443 }
2315 2444
2316 // Print total fragmentation for class and data metaspaces separately 2445 // Print total fragmentation for class and data metaspaces separately
2317 void MetaspaceAux::print_waste(outputStream* out) { 2446 void MetaspaceAux::print_waste(outputStream* out) {
2318 2447
2319 size_t small_waste = 0, medium_waste = 0, large_waste = 0; 2448 size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0;
2320 size_t cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; 2449 size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 0;
2450 size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0;
2451 size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_large_count = 0;
2321 2452
2322 ClassLoaderDataGraphMetaspaceIterator iter; 2453 ClassLoaderDataGraphMetaspaceIterator iter;
2323 while (iter.repeat()) { 2454 while (iter.repeat()) {
2324 Metaspace* msp = iter.get_next(); 2455 Metaspace* msp = iter.get_next();
2325 if (msp != NULL) { 2456 if (msp != NULL) {
2457 specialized_waste += msp->vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
2458 specialized_count += msp->vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
2326 small_waste += msp->vsm()->sum_waste_in_chunks_in_use(SmallIndex); 2459 small_waste += msp->vsm()->sum_waste_in_chunks_in_use(SmallIndex);
2460 small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex);
2327 medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); 2461 medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex);
2462 medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex);
2328 large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex); 2463 large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex);
2329 2464 large_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex);
2465
2466 cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
2467 cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
2330 cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex); 2468 cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex);
2469 cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex);
2331 cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex); 2470 cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex);
2471 cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex);
2332 cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex); 2472 cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex);
2473 cls_large_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
2333 } 2474 }
2334 } 2475 }
2335 out->print_cr("Total fragmentation waste (words) doesn't count free space"); 2476 out->print_cr("Total fragmentation waste (words) doesn't count free space");
2336 out->print(" data: small " SIZE_FORMAT " medium " SIZE_FORMAT, 2477 out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
2337 small_waste, medium_waste); 2478 SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
2338 out->print_cr(" class: small " SIZE_FORMAT, cls_small_waste); 2479 SIZE_FORMAT " medium(s) " SIZE_FORMAT,
2480 specialized_count, specialized_waste, small_count,
2481 small_waste, medium_count, medium_waste);
2482 out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
2483 SIZE_FORMAT " small(s) " SIZE_FORMAT,
2484 cls_specialized_count, cls_specialized_waste,
2485 cls_small_count, cls_small_waste);
2339 } 2486 }
2340 2487
2341 // Dump global metaspace things from the end of ClassLoaderDataGraph 2488 // Dump global metaspace things from the end of ClassLoaderDataGraph
2342 void MetaspaceAux::dump(outputStream* out) { 2489 void MetaspaceAux::dump(outputStream* out) {
2343 out->print_cr("All Metaspace:"); 2490 out->print_cr("All Metaspace:");
2352 } 2499 }
2353 2500
2354 // Metaspace methods 2501 // Metaspace methods
2355 2502
2356 size_t Metaspace::_first_chunk_word_size = 0; 2503 size_t Metaspace::_first_chunk_word_size = 0;
2357 2504 size_t Metaspace::_first_class_chunk_word_size = 0;
2358 Metaspace::Metaspace(Mutex* lock, size_t word_size) { 2505
2359 initialize(lock, word_size); 2506 Metaspace::Metaspace(Mutex* lock, MetaspaceType type) {
2360 } 2507 initialize(lock, type);
2361
2362 Metaspace::Metaspace(Mutex* lock) {
2363 initialize(lock);
2364 } 2508 }
2365 2509
2366 Metaspace::~Metaspace() { 2510 Metaspace::~Metaspace() {
2367 delete _vsm; 2511 delete _vsm;
2368 delete _class_vsm; 2512 delete _class_vsm;
2410 assert(!mapinfo->is_open() && !UseSharedSpaces, 2554 assert(!mapinfo->is_open() && !UseSharedSpaces,
2411 "archive file not closed or shared spaces not disabled."); 2555 "archive file not closed or shared spaces not disabled.");
2412 } 2556 }
2413 } 2557 }
2414 2558
2415 // Initialize this before initializing the VirtualSpaceList 2559 // Initialize these before initializing the VirtualSpaceList
2416 _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord; 2560 _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
2561 _first_chunk_word_size = align_word_size_up(_first_chunk_word_size);
2562 // Make the first class chunk bigger than a medium chunk so it's not put
2563 // on the medium chunk list. The next chunk will be small and progress
2564 // from there. This size calculated by -version.
2565 _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6,
2566 (ClassMetaspaceSize/BytesPerWord)*2);
2567 _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
2417 // Arbitrarily set the initial virtual space to a multiple 2568 // Arbitrarily set the initial virtual space to a multiple
2418 // of the boot class loader size. 2569 // of the boot class loader size.
2419 size_t word_size = VIRTUALSPACEMULTIPLIER * Metaspace::first_chunk_word_size(); 2570 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size();
2420 // Initialize the list of virtual spaces. 2571 // Initialize the list of virtual spaces.
2421 _space_list = new VirtualSpaceList(word_size); 2572 _space_list = new VirtualSpaceList(word_size);
2422 } 2573 }
2423 } 2574 }
2424 2575
2429 // The reserved space size may be bigger because of alignment, esp with UseLargePages 2580 // The reserved space size may be bigger because of alignment, esp with UseLargePages
2430 assert(rs.size() >= ClassMetaspaceSize, err_msg("%d != %d", rs.size(), ClassMetaspaceSize)); 2581 assert(rs.size() >= ClassMetaspaceSize, err_msg("%d != %d", rs.size(), ClassMetaspaceSize));
2431 _class_space_list = new VirtualSpaceList(rs); 2582 _class_space_list = new VirtualSpaceList(rs);
2432 } 2583 }
2433 2584
2434 2585 void Metaspace::initialize(Mutex* lock,
2435 void Metaspace::initialize(Mutex* lock, size_t initial_size) { 2586 MetaspaceType type) {
2436 // Use SmallChunk size if not specified. If specified, use this size for
2437 // the data metaspace.
2438 size_t word_size;
2439 size_t class_word_size;
2440 if (initial_size == 0) {
2441 word_size = (size_t) SpaceManager::SmallChunk;
2442 class_word_size = (size_t) SpaceManager::SmallChunk;
2443 } else {
2444 word_size = initial_size;
2445 // Make the first class chunk bigger than a medium chunk so it's not put
2446 // on the medium chunk list. The next chunk will be small and progress
2447 // from there. This size calculated by -version.
2448 class_word_size = MIN2((size_t)SpaceManager::MediumChunk*5,
2449 (ClassMetaspaceSize/BytesPerWord)*2);
2450 }
2451 2587
2452 assert(space_list() != NULL, 2588 assert(space_list() != NULL,
2453 "Metadata VirtualSpaceList has not been initialized"); 2589 "Metadata VirtualSpaceList has not been initialized");
2454 2590
2455 _vsm = new SpaceManager(lock, space_list()); 2591 _vsm = new SpaceManager(lock, space_list());
2456 if (_vsm == NULL) { 2592 if (_vsm == NULL) {
2457 return; 2593 return;
2458 } 2594 }
2595 size_t word_size;
2596 size_t class_word_size;
2597 vsm()->get_initial_chunk_sizes(type,
2598 &word_size,
2599 &class_word_size);
2459 2600
2460 assert(class_space_list() != NULL, 2601 assert(class_space_list() != NULL,
2461 "Class VirtualSpaceList has not been initialized"); 2602 "Class VirtualSpaceList has not been initialized");
2462 2603
2463 // Allocate SpaceManager for classes. 2604 // Allocate SpaceManager for classes.
2468 2609
2469 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); 2610 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
2470 2611
2471 // Allocate chunk for metadata objects 2612 // Allocate chunk for metadata objects
2472 Metachunk* new_chunk = 2613 Metachunk* new_chunk =
2473 space_list()->current_virtual_space()->get_chunk_vs_with_expand(word_size); 2614 space_list()->get_initialization_chunk(word_size,
2615 vsm()->medium_chunk_bunch());
2474 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); 2616 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks");
2475 if (new_chunk != NULL) { 2617 if (new_chunk != NULL) {
2476 // Add to this manager's list of chunks in use and current_chunk(). 2618 // Add to this manager's list of chunks in use and current_chunk().
2477 vsm()->add_chunk(new_chunk, true); 2619 vsm()->add_chunk(new_chunk, true);
2478 } 2620 }
2479 2621
2480 // Allocate chunk for class metadata objects 2622 // Allocate chunk for class metadata objects
2481 Metachunk* class_chunk = 2623 Metachunk* class_chunk =
2482 class_space_list()->current_virtual_space()->get_chunk_vs_with_expand(class_word_size); 2624 class_space_list()->get_initialization_chunk(class_word_size,
2625 class_vsm()->medium_chunk_bunch());
2483 if (class_chunk != NULL) { 2626 if (class_chunk != NULL) {
2484 class_vsm()->add_chunk(class_chunk, true); 2627 class_vsm()->add_chunk(class_chunk, true);
2485 } 2628 }
2629 }
2630
2631 size_t Metaspace::align_word_size_up(size_t word_size) {
2632 size_t byte_size = word_size * wordSize;
2633 return ReservedSpace::allocation_align_size_up(byte_size) / wordSize;
2486 } 2634 }
2487 2635
2488 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { 2636 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
2489 // DumpSharedSpaces doesn't use class metadata area (yet) 2637 // DumpSharedSpaces doesn't use class metadata area (yet)
2490 if (mdtype == ClassType && !DumpSharedSpaces) { 2638 if (mdtype == ClassType && !DumpSharedSpaces) {
2608 Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation( 2756 Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
2609 loader_data, word_size, mdtype); 2757 loader_data, word_size, mdtype);
2610 2758
2611 // If result is still null, we are out of memory. 2759 // If result is still null, we are out of memory.
2612 if (result == NULL) { 2760 if (result == NULL) {
2761 if (Verbose && TraceMetadataChunkAllocation) {
2762 gclog_or_tty->print_cr("Metaspace allocation failed for size "
2763 SIZE_FORMAT, word_size);
2764 if (loader_data->metaspace_or_null() != NULL) loader_data->metaspace_or_null()->dump(gclog_or_tty);
2765 MetaspaceAux::dump(gclog_or_tty);
2766 }
2613 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support 2767 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
2614 report_java_out_of_memory("Metadata space"); 2768 report_java_out_of_memory("Metadata space");
2615 2769
2616 if (JvmtiExport::should_post_resource_exhausted()) { 2770 if (JvmtiExport::should_post_resource_exhausted()) {
2617 JvmtiExport::post_resource_exhausted( 2771 JvmtiExport::post_resource_exhausted(