// Call function for all symbols in the symbol table. void SymbolTable::symbols_do(SymbolClosure *cl) { const int n = the_table()->table_size(); for (int i = 0; i < n; i++) { for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); p != NULL; p = p->next()) { cl->do_symbol(p->literal_addr()); } } }
symbolOop SymbolTable::lookup(const char* name, int len, TRAPS) { unsigned int hashValue = hash_symbol(name, len); int index = the_table()->hash_to_index(hashValue); symbolOop s = the_table()->lookup(index, name, len, hashValue); // Found if (s != NULL) return s; // Otherwise, add to symbol to table return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL); }
Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) { unsigned int hashValue = hash_symbol(name, len); int index = the_table()->hash_to_index(hashValue); Symbol* s = the_table()->lookup(index, name, len, hashValue); // Found if (s != NULL) return s; // Grab SymbolTable_lock first. MutexLocker ml(SymbolTable_lock, THREAD); // Otherwise, add to symbol to table return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL); }
symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) { char* buffer; int index, len; unsigned int hashValue; char* name; { debug_only(No_Safepoint_Verifier nsv;) name = (char*)sym->base() + begin; len = end - begin; hashValue = hash_symbol(name, len); index = the_table()->hash_to_index(hashValue); symbolOop s = the_table()->lookup(index, name, len, hashValue); // Found if (s != NULL) return s; }
// 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); } }
// Create a new table and using alternate hash code, populate the new table // with the existing strings. Set flag to use the alternate hash code afterwards. void SymbolTable::rehash_table() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); // This should never happen with -Xshare:dump but it might in testing mode. if (DumpSharedSpaces) return; // Create a new symbol table SymbolTable* new_table = new SymbolTable(); the_table()->move_to(new_table); // Delete the table and buckets (entries are reused in new table). delete _the_table; // Don't check if we need rehashing until the table gets unbalanced again. // Then rehash with a new global seed. _needs_rehashing = false; _the_table = new_table; }
static void reverse() { the_table()->Hashtable<oop, mtSymbol>::reverse(); }
static void copy_table(char** top, char*end) { the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end); }