// Remove unreferenced symbols from the symbol table // This is done late during GC. void SymbolTable::unlink() { int removed = 0; int total = 0; size_t memory_total = 0; for (int i = 0; i < the_table()->table_size(); ++i) { HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i); HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i); while (entry != NULL) { // Shared entries are normally at the end of the bucket and if we run into // a shared entry, then there is nothing more to remove. However, if we // have rehashed the table, then the shared entries are no longer at the // end of the bucket. if (entry->is_shared() && !use_alternate_hashcode()) { break; } Symbol* s = entry->literal(); memory_total += s->object_size(); total++; assert(s != NULL, "just checking"); // If reference count is zero, remove. if (s->refcount() == 0) { assert(!entry->is_shared(), "shared entries should be kept live"); delete s; removed++; *p = entry->next(); the_table()->free_entry(entry); } else { p = entry->next_addr(); } // get next entry entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p); } } symbols_removed += removed; symbols_counted += total; // Exclude printing for normal PrintGCDetails because people parse // this output. if (PrintGCDetails && Verbose && WizardMode) { gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", total, (memory_total*HeapWordSize)/1024); } }