comparison src/share/vm/classfile/symbolTable.cpp @ 14909:4ca6dc0799b6

Backout jdk9 merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 01 Apr 2014 13:57:07 +0200
parents 893ce66f7473
children 52b4284cb496
comparison
equal deleted inserted replaced
14908:8db6e76cb658 14909:4ca6dc0799b6
36 #include "runtime/mutexLocker.hpp" 36 #include "runtime/mutexLocker.hpp"
37 #include "utilities/hashtable.inline.hpp" 37 #include "utilities/hashtable.inline.hpp"
38 38
39 // -------------------------------------------------------------------------- 39 // --------------------------------------------------------------------------
40 40
41 // the number of buckets a thread claims
42 const int ClaimChunkSize = 32;
43
44 SymbolTable* SymbolTable::_the_table = NULL; 41 SymbolTable* SymbolTable::_the_table = NULL;
45 // Static arena for symbols that are not deallocated 42 // Static arena for symbols that are not deallocated
46 Arena* SymbolTable::_arena = NULL; 43 Arena* SymbolTable::_arena = NULL;
47 bool SymbolTable::_needs_rehashing = false; 44 bool SymbolTable::_needs_rehashing = false;
48 45
84 cl->do_symbol(p->literal_addr()); 81 cl->do_symbol(p->literal_addr());
85 } 82 }
86 } 83 }
87 } 84 }
88 85
89 int SymbolTable::_symbols_removed = 0; 86 int SymbolTable::symbols_removed = 0;
90 int SymbolTable::_symbols_counted = 0; 87 int SymbolTable::symbols_counted = 0;
91 volatile int SymbolTable::_parallel_claimed_idx = 0; 88
92 89 // Remove unreferenced symbols from the symbol table
93 void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total) { 90 // This is done late during GC.
94 for (int i = start_idx; i < end_idx; ++i) { 91 void SymbolTable::unlink() {
92 int removed = 0;
93 int total = 0;
94 size_t memory_total = 0;
95 for (int i = 0; i < the_table()->table_size(); ++i) {
95 HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i); 96 HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
96 HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i); 97 HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
97 while (entry != NULL) { 98 while (entry != NULL) {
98 // Shared entries are normally at the end of the bucket and if we run into 99 // Shared entries are normally at the end of the bucket and if we run into
99 // a shared entry, then there is nothing more to remove. However, if we 100 // a shared entry, then there is nothing more to remove. However, if we
101 // end of the bucket. 102 // end of the bucket.
102 if (entry->is_shared() && !use_alternate_hashcode()) { 103 if (entry->is_shared() && !use_alternate_hashcode()) {
103 break; 104 break;
104 } 105 }
105 Symbol* s = entry->literal(); 106 Symbol* s = entry->literal();
106 (*memory_total) += s->size(); 107 memory_total += s->size();
107 (*processed)++; 108 total++;
108 assert(s != NULL, "just checking"); 109 assert(s != NULL, "just checking");
109 // If reference count is zero, remove. 110 // If reference count is zero, remove.
110 if (s->refcount() == 0) { 111 if (s->refcount() == 0) {
111 assert(!entry->is_shared(), "shared entries should be kept live"); 112 assert(!entry->is_shared(), "shared entries should be kept live");
112 delete s; 113 delete s;
113 (*removed)++; 114 removed++;
114 *p = entry->next(); 115 *p = entry->next();
115 the_table()->free_entry(entry); 116 the_table()->free_entry(entry);
116 } else { 117 } else {
117 p = entry->next_addr(); 118 p = entry->next_addr();
118 } 119 }
119 // get next entry 120 // get next entry
120 entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p); 121 entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);
121 } 122 }
122 } 123 }
123 } 124 symbols_removed += removed;
124 125 symbols_counted += total;
125 // Remove unreferenced symbols from the symbol table
126 // This is done late during GC.
127 void SymbolTable::unlink(int* processed, int* removed) {
128 size_t memory_total = 0;
129 buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total);
130 _symbols_removed += *removed;
131 _symbols_counted += *processed;
132 // Exclude printing for normal PrintGCDetails because people parse 126 // Exclude printing for normal PrintGCDetails because people parse
133 // this output. 127 // this output.
134 if (PrintGCDetails && Verbose && WizardMode) { 128 if (PrintGCDetails && Verbose && WizardMode) {
135 gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed, 129 gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", total,
136 (memory_total*HeapWordSize)/1024);
137 }
138 }
139
140 void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {
141 const int limit = the_table()->table_size();
142
143 size_t memory_total = 0;
144
145 for (;;) {
146 // Grab next set of buckets to scan
147 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
148 if (start_idx >= limit) {
149 // End of table
150 break;
151 }
152
153 int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
154 buckets_unlink(start_idx, end_idx, processed, removed, &memory_total);
155 }
156 Atomic::add(*processed, &_symbols_counted);
157 Atomic::add(*removed, &_symbols_removed);
158 // Exclude printing for normal PrintGCDetails because people parse
159 // this output.
160 if (PrintGCDetails && Verbose && WizardMode) {
161 gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed,
162 (memory_total*HeapWordSize)/1024); 130 (memory_total*HeapWordSize)/1024);
163 } 131 }
164 } 132 }
165 133
166 // Create a new table and using alternate hash code, populate the new table 134 // Create a new table and using alternate hash code, populate the new table
524 } 492 }
525 tty->print_cr("Symbol Table:"); 493 tty->print_cr("Symbol Table:");
526 tty->print_cr("Total number of symbols %5d", count); 494 tty->print_cr("Total number of symbols %5d", count);
527 tty->print_cr("Total size in memory %5dK", 495 tty->print_cr("Total size in memory %5dK",
528 (memory_total*HeapWordSize)/1024); 496 (memory_total*HeapWordSize)/1024);
529 tty->print_cr("Total counted %5d", _symbols_counted); 497 tty->print_cr("Total counted %5d", symbols_counted);
530 tty->print_cr("Total removed %5d", _symbols_removed); 498 tty->print_cr("Total removed %5d", symbols_removed);
531 if (_symbols_counted > 0) { 499 if (symbols_counted > 0) {
532 tty->print_cr("Percent removed %3.2f", 500 tty->print_cr("Percent removed %3.2f",
533 ((float)_symbols_removed/(float)_symbols_counted)* 100); 501 ((float)symbols_removed/(float)symbols_counted)* 100);
534 } 502 }
535 tty->print_cr("Reference counts %5d", Symbol::_total_count); 503 tty->print_cr("Reference counts %5d", Symbol::_total_count);
536 tty->print_cr("Symbol arena size %5d used %5d", 504 tty->print_cr("Symbol arena size %5d used %5d",
537 arena()->size_in_bytes(), arena()->used()); 505 arena()->size_in_bytes(), arena()->used());
538 tty->print_cr("Histogram of symbol length:"); 506 tty->print_cr("Histogram of symbol length:");
769 Handle string; 737 Handle string;
770 oop result = intern(string, chars, length, CHECK_NULL); 738 oop result = intern(string, chars, length, CHECK_NULL);
771 return result; 739 return result;
772 } 740 }
773 741
774 void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) { 742 void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
775 buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed);
776 }
777
778 void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
779 // Readers of the table are unlocked, so we should only be removing 743 // Readers of the table are unlocked, so we should only be removing
780 // entries at a safepoint. 744 // entries at a safepoint.
781 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 745 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
782 const int limit = the_table()->table_size(); 746 for (int i = 0; i < the_table()->table_size(); ++i) {
783
784 for (;;) {
785 // Grab next set of buckets to scan
786 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
787 if (start_idx >= limit) {
788 // End of table
789 break;
790 }
791
792 int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
793 buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed);
794 }
795 }
796
797 void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {
798 const int limit = the_table()->table_size();
799
800 assert(0 <= start_idx && start_idx <= limit,
801 err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));
802 assert(0 <= end_idx && end_idx <= limit,
803 err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));
804 assert(start_idx <= end_idx,
805 err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
806 start_idx, end_idx));
807
808 for (int i = start_idx; i < end_idx; i += 1) {
809 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
810 while (entry != NULL) {
811 assert(!entry->is_shared(), "CDS not used for the StringTable");
812
813 f->do_oop((oop*)entry->literal_addr());
814
815 entry = entry->next();
816 }
817 }
818 }
819
820 void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) {
821 const int limit = the_table()->table_size();
822
823 assert(0 <= start_idx && start_idx <= limit,
824 err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));
825 assert(0 <= end_idx && end_idx <= limit,
826 err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));
827 assert(start_idx <= end_idx,
828 err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
829 start_idx, end_idx));
830
831 for (int i = start_idx; i < end_idx; ++i) {
832 HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); 747 HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
833 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); 748 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
834 while (entry != NULL) { 749 while (entry != NULL) {
835 assert(!entry->is_shared(), "CDS not used for the StringTable"); 750 assert(!entry->is_shared(), "CDS not used for the StringTable");
836 751
840 } 755 }
841 p = entry->next_addr(); 756 p = entry->next_addr();
842 } else { 757 } else {
843 *p = entry->next(); 758 *p = entry->next();
844 the_table()->free_entry(entry); 759 the_table()->free_entry(entry);
845 (*removed)++; 760 }
846 }
847 (*processed)++;
848 entry = *p; 761 entry = *p;
849 } 762 }
850 } 763 }
851 } 764 }
852 765
766 void StringTable::buckets_do(OopClosure* f, int start_idx, int end_idx) {
767 const int limit = the_table()->table_size();
768
769 assert(0 <= start_idx && start_idx <= limit,
770 err_msg("start_idx (" INT32_FORMAT ") oob?", start_idx));
771 assert(0 <= end_idx && end_idx <= limit,
772 err_msg("end_idx (" INT32_FORMAT ") oob?", end_idx));
773 assert(start_idx <= end_idx,
774 err_msg("Ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
775 start_idx, end_idx));
776
777 for (int i = start_idx; i < end_idx; i += 1) {
778 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
779 while (entry != NULL) {
780 assert(!entry->is_shared(), "CDS not used for the StringTable");
781
782 f->do_oop((oop*)entry->literal_addr());
783
784 entry = entry->next();
785 }
786 }
787 }
788
853 void StringTable::oops_do(OopClosure* f) { 789 void StringTable::oops_do(OopClosure* f) {
854 buckets_oops_do(f, 0, the_table()->table_size()); 790 buckets_do(f, 0, the_table()->table_size());
855 } 791 }
856 792
857 void StringTable::possibly_parallel_oops_do(OopClosure* f) { 793 void StringTable::possibly_parallel_oops_do(OopClosure* f) {
794 const int ClaimChunkSize = 32;
858 const int limit = the_table()->table_size(); 795 const int limit = the_table()->table_size();
859 796
860 for (;;) { 797 for (;;) {
861 // Grab next set of buckets to scan 798 // Grab next set of buckets to scan
862 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; 799 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
864 // End of table 801 // End of table
865 break; 802 break;
866 } 803 }
867 804
868 int end_idx = MIN2(limit, start_idx + ClaimChunkSize); 805 int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
869 buckets_oops_do(f, start_idx, end_idx); 806 buckets_do(f, start_idx, end_idx);
870 } 807 }
871 } 808 }
872 809
873 // This verification is part of Universe::verify() and needs to be quick. 810 // This verification is part of Universe::verify() and needs to be quick.
874 // See StringTable::verify_and_compare() below for exhaustive verification. 811 // See StringTable::verify_and_compare() below for exhaustive verification.