symbolOop SymbolTable::lookup(int index, const char* name, int len, unsigned int hash) { for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { if (e->hash() == hash) { symbolOop sym = symbolOop(e->literal()); if (sym->equals(name, len)) { return sym; } } } return NULL; }
// 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); } }
Symbol* SymbolTable::lookup(int index, const char* name, int len, unsigned int hash) { int count = 0; for (HashtableEntry<Symbol*, mtSymbol>* e = bucket(index); e != NULL; e = e->next()) { count++; // count all entries in this bucket, not just ones with same hash if (e->hash() == hash) { Symbol* sym = e->literal(); if (sym->equals(name, len)) { // something is referencing this symbol now. sym->increment_refcount(); return sym; } } } // If the bucket size is too deep check if this hash code is insufficient. if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) { _needs_rehashing = check_rehash_table(count); } return NULL; }