119 delete s; 120 (*removed)++; 121 *p = entry->next(); 122 the_table()->free_entry(entry); 123 } else { 124 p = entry->next_addr(); 125 } 126 // get next entry 127 entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p); 128 } 129 } 130 } 131 132 // Remove unreferenced symbols from the symbol table 133 // This is done late during GC. 134 void SymbolTable::unlink(int* processed, int* removed) { 135 size_t memory_total = 0; 136 buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total); 137 _symbols_removed += *removed; 138 _symbols_counted += *processed; 139 // Exclude printing for normal PrintGCDetails because people parse 140 // this output. 141 if (PrintGCDetails && Verbose && WizardMode) { 142 gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed, 143 (memory_total*HeapWordSize)/1024); 144 } 145 } 146 147 void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) { 148 const int limit = the_table()->table_size(); 149 150 size_t memory_total = 0; 151 152 for (;;) { 153 // Grab next set of buckets to scan 154 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; 155 if (start_idx >= limit) { 156 // End of table 157 break; 158 } 159 160 int end_idx = MIN2(limit, start_idx + ClaimChunkSize); 161 buckets_unlink(start_idx, end_idx, processed, removed, &memory_total); 162 } 163 Atomic::add(*processed, &_symbols_counted); 164 Atomic::add(*removed, &_symbols_removed); 165 // Exclude printing for normal PrintGCDetails because people parse 166 // this output. 167 if (PrintGCDetails && Verbose && WizardMode) { 168 gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed, 169 (memory_total*HeapWordSize)/1024); 170 } 171 } 172 173 // Create a new table and using alternate hash code, populate the new table 174 // with the existing strings. Set flag to use the alternate hash code afterwards. 175 void SymbolTable::rehash_table() { 176 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 177 // This should never happen with -Xshare:dump but it might in testing mode. 178 if (DumpSharedSpaces) return; 179 // Create a new symbol table 180 SymbolTable* new_table = new SymbolTable(); 181 182 the_table()->move_to(new_table); 183 184 // Delete the table and buckets (entries are reused in new table). 185 delete _the_table; 186 // Don't check if we need rehashing until the table gets unbalanced again. 187 // Then rehash with a new global seed. 188 _needs_rehashing = false; | 119 delete s; 120 (*removed)++; 121 *p = entry->next(); 122 the_table()->free_entry(entry); 123 } else { 124 p = entry->next_addr(); 125 } 126 // get next entry 127 entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p); 128 } 129 } 130 } 131 132 // Remove unreferenced symbols from the symbol table 133 // This is done late during GC. 134 void SymbolTable::unlink(int* processed, int* removed) { 135 size_t memory_total = 0; 136 buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total); 137 _symbols_removed += *removed; 138 _symbols_counted += *processed; 139 if (Verbose && WizardMode) { 140 tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed, 141 (memory_total*HeapWordSize)/1024); 142 } 143 } 144 145 void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) { 146 const int limit = the_table()->table_size(); 147 148 size_t memory_total = 0; 149 150 for (;;) { 151 // Grab next set of buckets to scan 152 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; 153 if (start_idx >= limit) { 154 // End of table 155 break; 156 } 157 158 int end_idx = MIN2(limit, start_idx + ClaimChunkSize); 159 buckets_unlink(start_idx, end_idx, processed, removed, &memory_total); 160 } 161 Atomic::add(*processed, &_symbols_counted); 162 Atomic::add(*removed, &_symbols_removed); 163 if (Verbose && WizardMode) { 164 tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed, 165 (memory_total*HeapWordSize)/1024); 166 } 167 } 168 169 // Create a new table and using alternate hash code, populate the new table 170 // with the existing strings. Set flag to use the alternate hash code afterwards. 171 void SymbolTable::rehash_table() { 172 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 173 // This should never happen with -Xshare:dump but it might in testing mode. 174 if (DumpSharedSpaces) return; 175 // Create a new symbol table 176 SymbolTable* new_table = new SymbolTable(); 177 178 the_table()->move_to(new_table); 179 180 // Delete the table and buckets (entries are reused in new table). 181 delete _the_table; 182 // Don't check if we need rehashing until the table gets unbalanced again. 183 // Then rehash with a new global seed. 184 _needs_rehashing = false; |