Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/symbolTable.cpp
32285 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/altHashing.hpp"26#include "classfile/javaClasses.hpp"27#include "classfile/symbolTable.hpp"28#include "classfile/systemDictionary.hpp"29#include "gc_interface/collectedHeap.inline.hpp"30#include "memory/allocation.inline.hpp"31#include "memory/filemap.hpp"32#include "memory/gcLocker.inline.hpp"33#include "oops/oop.inline.hpp"34#include "oops/oop.inline2.hpp"35#include "runtime/mutexLocker.hpp"36#include "utilities/hashtable.inline.hpp"37#if INCLUDE_ALL_GCS38#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"39#include "gc_implementation/g1/g1StringDedup.hpp"40#endif4142PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC4344// --------------------------------------------------------------------------4546// the number of buckets a thread claims47const int ClaimChunkSize = 32;4849SymbolTable* SymbolTable::_the_table = NULL;50// Static arena for symbols that are not deallocated51Arena* SymbolTable::_arena = NULL;52bool SymbolTable::_needs_rehashing = false;5354Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {55assert (len <= Symbol::max_length(), "should be checked by caller");5657Symbol* sym;5859if (DumpSharedSpaces) {60// Allocate all symbols to CLD shared metaspace61sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);62} else if (c_heap) {63// refcount starts as 164sym = new (len, THREAD) Symbol(name, len, 1);65assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");66} else {67// Allocate to global arena68sym = new (len, arena(), THREAD) Symbol(name, len, -1);69}70return sym;71}7273void SymbolTable::initialize_symbols(int arena_alloc_size) {74// Initialize the arena for global symbols, size passed in depends on CDS.75if (arena_alloc_size == 0) {76_arena = new (mtSymbol) Arena(mtSymbol);77} else {78_arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size);79}80}8182// Call function for all symbols in the symbol table.83void SymbolTable::symbols_do(SymbolClosure *cl) {84const int n = the_table()->table_size();85for (int i = 0; i < n; i++) {86for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);87p != NULL;88p = p->next()) {89cl->do_symbol(p->literal_addr());90}91}92}9394int SymbolTable::_symbols_removed = 0;95int SymbolTable::_symbols_counted = 0;96volatile int SymbolTable::_parallel_claimed_idx = 0;9798void SymbolTable::buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context, size_t* memory_total) {99for (int i = start_idx; i < end_idx; ++i) {100HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);101HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);102while (entry != NULL) {103// Shared entries are normally at the end of the bucket and if we run into104// a shared entry, then there is nothing more to remove. However, if we105// have rehashed the table, then the shared entries are no longer at the106// end of the bucket.107if (entry->is_shared() && !use_alternate_hashcode()) {108break;109}110Symbol* s = entry->literal();111(*memory_total) += s->size();112context->_num_processed++;113assert(s != NULL, "just checking");114// If reference count is zero, remove.115if (s->refcount() == 0) {116assert(!entry->is_shared(), "shared entries should be kept live");117delete s;118*p = entry->next();119context->free_entry(entry);120} else {121p = entry->next_addr();122}123// get next entry124entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);125}126}127}128129// Remove unreferenced symbols from the symbol table130// This is done late during GC.131void SymbolTable::unlink(int* processed, int* removed) {132size_t memory_total = 0;133BucketUnlinkContext context;134buckets_unlink(0, the_table()->table_size(), &context, &memory_total);135_the_table->bulk_free_entries(&context);136*processed = context._num_processed;137*removed = context._num_removed;138139_symbols_removed = context._num_removed;140_symbols_counted = context._num_processed;141// Exclude printing for normal PrintGCDetails because people parse142// this output.143if (PrintGCDetails && Verbose && WizardMode) {144gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed,145(memory_total*HeapWordSize)/1024);146}147}148149void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {150const int limit = the_table()->table_size();151152size_t memory_total = 0;153154BucketUnlinkContext context;155for (;;) {156// Grab next set of buckets to scan157int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;158if (start_idx >= limit) {159// End of table160break;161}162163int end_idx = MIN2(limit, start_idx + ClaimChunkSize);164buckets_unlink(start_idx, end_idx, &context, &memory_total);165}166167_the_table->bulk_free_entries(&context);168*processed = context._num_processed;169*removed = context._num_removed;170171Atomic::add(context._num_processed, &_symbols_counted);172Atomic::add(context._num_removed, &_symbols_removed);173// Exclude printing for normal PrintGCDetails because people parse174// this output.175if (PrintGCDetails && Verbose && WizardMode) {176gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed,177(memory_total*HeapWordSize)/1024);178}179}180181// Create a new table and using alternate hash code, populate the new table182// with the existing strings. Set flag to use the alternate hash code afterwards.183void SymbolTable::rehash_table() {184assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");185// This should never happen with -Xshare:dump but it might in testing mode.186if (DumpSharedSpaces) return;187// Create a new symbol table188SymbolTable* new_table = new SymbolTable();189190the_table()->move_to(new_table);191192// Delete the table and buckets (entries are reused in new table).193delete _the_table;194// Don't check if we need rehashing until the table gets unbalanced again.195// Then rehash with a new global seed.196_needs_rehashing = false;197_the_table = new_table;198}199200// Lookup a symbol in a bucket.201202Symbol* SymbolTable::lookup(int index, const char* name,203int len, unsigned int hash) {204int count = 0;205for (HashtableEntry<Symbol*, mtSymbol>* e = bucket(index); e != NULL; e = e->next()) {206count++; // count all entries in this bucket, not just ones with same hash207if (e->hash() == hash) {208Symbol* sym = e->literal();209if (sym->equals(name, len)) {210// something is referencing this symbol now.211sym->increment_refcount();212return sym;213}214}215}216// If the bucket size is too deep check if this hash code is insufficient.217if (count >= rehash_count && !needs_rehashing()) {218_needs_rehashing = check_rehash_table(count);219}220return NULL;221}222223// Pick hashing algorithm.224unsigned int SymbolTable::hash_symbol(const char* s, int len) {225return use_alternate_hashcode() ?226AltHashing::halfsiphash_32(seed(), (const uint8_t*)s, len) :227java_lang_String::hash_code(s, len);228}229230231// We take care not to be blocking while holding the232// SymbolTable_lock. Otherwise, the system might deadlock, since the233// symboltable is used during compilation (VM_thread) The lock free234// synchronization is simplified by the fact that we do not delete235// entries in the symbol table during normal execution (only during236// safepoints).237238Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {239unsigned int hashValue = hash_symbol(name, len);240int index = the_table()->hash_to_index(hashValue);241242Symbol* s = the_table()->lookup(index, name, len, hashValue);243244// Found245if (s != NULL) return s;246247// Grab SymbolTable_lock first.248MutexLocker ml(SymbolTable_lock, THREAD);249250// Otherwise, add to symbol to table251return the_table()->basic_add(index, (u1*)name, len, hashValue, true, THREAD);252}253254Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {255char* buffer;256int index, len;257unsigned int hashValue;258char* name;259{260debug_only(No_Safepoint_Verifier nsv;)261262name = (char*)sym->base() + begin;263len = end - begin;264hashValue = hash_symbol(name, len);265index = the_table()->hash_to_index(hashValue);266Symbol* s = the_table()->lookup(index, name, len, hashValue);267268// Found269if (s != NULL) return s;270}271272// Otherwise, add to symbol to table. Copy to a C string first.273char stack_buf[128];274ResourceMark rm(THREAD);275if (len <= 128) {276buffer = stack_buf;277} else {278buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);279}280for (int i=0; i<len; i++) {281buffer[i] = name[i];282}283// Make sure there is no safepoint in the code above since name can't move.284// We can't include the code in No_Safepoint_Verifier because of the285// ResourceMark.286287// Grab SymbolTable_lock first.288MutexLocker ml(SymbolTable_lock, THREAD);289290return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, THREAD);291}292293Symbol* SymbolTable::lookup_only(const char* name, int len,294unsigned int& hash) {295hash = hash_symbol(name, len);296int index = the_table()->hash_to_index(hash);297298Symbol* s = the_table()->lookup(index, name, len, hash);299return s;300}301302// Look up the address of the literal in the SymbolTable for this Symbol*303// Do not create any new symbols304// Do not increment the reference count to keep this alive305Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){306unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length());307int index = the_table()->hash_to_index(hash);308309for (HashtableEntry<Symbol*, mtSymbol>* e = the_table()->bucket(index); e != NULL; e = e->next()) {310if (e->hash() == hash) {311Symbol* literal_sym = e->literal();312if (sym == literal_sym) {313return e->literal_addr();314}315}316}317return NULL;318}319320// Suggestion: Push unicode-based lookup all the way into the hashing321// and probing logic, so there is no need for convert_to_utf8 until322// an actual new Symbol* is created.323Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {324int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);325char stack_buf[128];326if (utf8_length < (int) sizeof(stack_buf)) {327char* chars = stack_buf;328UNICODE::convert_to_utf8(name, utf16_length, chars);329return lookup(chars, utf8_length, THREAD);330} else {331ResourceMark rm(THREAD);332char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;333UNICODE::convert_to_utf8(name, utf16_length, chars);334return lookup(chars, utf8_length, THREAD);335}336}337338Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,339unsigned int& hash) {340int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);341char stack_buf[128];342if (utf8_length < (int) sizeof(stack_buf)) {343char* chars = stack_buf;344UNICODE::convert_to_utf8(name, utf16_length, chars);345return lookup_only(chars, utf8_length, hash);346} else {347ResourceMark rm;348char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;349UNICODE::convert_to_utf8(name, utf16_length, chars);350return lookup_only(chars, utf8_length, hash);351}352}353354void SymbolTable::add(ClassLoaderData* loader_data, constantPoolHandle cp,355int names_count,356const char** names, int* lengths, int* cp_indices,357unsigned int* hashValues, TRAPS) {358// Grab SymbolTable_lock first.359MutexLocker ml(SymbolTable_lock, THREAD);360361SymbolTable* table = the_table();362bool added = table->basic_add(loader_data, cp, names_count, names, lengths,363cp_indices, hashValues, CHECK);364if (!added) {365// do it the hard way366for (int i=0; i<names_count; i++) {367int index = table->hash_to_index(hashValues[i]);368bool c_heap = !loader_data->is_the_null_class_loader_data();369Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], c_heap, CHECK);370cp->symbol_at_put(cp_indices[i], sym);371}372}373}374375Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {376unsigned int hash;377Symbol* result = SymbolTable::lookup_only((char*)name, (int)strlen(name), hash);378if (result != NULL) {379return result;380}381// Grab SymbolTable_lock first.382MutexLocker ml(SymbolTable_lock, THREAD);383384SymbolTable* table = the_table();385int index = table->hash_to_index(hash);386return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);387}388389Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len,390unsigned int hashValue_arg, bool c_heap, TRAPS) {391assert(!Universe::heap()->is_in_reserved(name),392"proposed name of symbol must be stable");393394// Don't allow symbols to be created which cannot fit in a Symbol*.395if (len > Symbol::max_length()) {396THROW_MSG_0(vmSymbols::java_lang_InternalError(),397"name is too long to represent");398}399400// Cannot hit a safepoint in this function because the "this" pointer can move.401No_Safepoint_Verifier nsv;402403// Check if the symbol table has been rehashed, if so, need to recalculate404// the hash value and index.405unsigned int hashValue;406int index;407if (use_alternate_hashcode()) {408hashValue = hash_symbol((const char*)name, len);409index = hash_to_index(hashValue);410} else {411hashValue = hashValue_arg;412index = index_arg;413}414415// Since look-up was done lock-free, we need to check if another416// thread beat us in the race to insert the symbol.417Symbol* test = lookup(index, (char*)name, len, hashValue);418if (test != NULL) {419// A race occurred and another thread introduced the symbol.420assert(test->refcount() != 0, "lookup should have incremented the count");421return test;422}423424// Create a new symbol.425Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL);426assert(sym->equals((char*)name, len), "symbol must be properly initialized");427428HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym);429add_entry(index, entry);430return sym;431}432433// This version of basic_add adds symbols in batch from the constant pool434// parsing.435bool SymbolTable::basic_add(ClassLoaderData* loader_data, constantPoolHandle cp,436int names_count,437const char** names, int* lengths,438int* cp_indices, unsigned int* hashValues,439TRAPS) {440441// Check symbol names are not too long. If any are too long, don't add any.442for (int i = 0; i< names_count; i++) {443if (lengths[i] > Symbol::max_length()) {444THROW_MSG_0(vmSymbols::java_lang_InternalError(),445"name is too long to represent");446}447}448449// Cannot hit a safepoint in this function because the "this" pointer can move.450No_Safepoint_Verifier nsv;451452for (int i=0; i<names_count; i++) {453// Check if the symbol table has been rehashed, if so, need to recalculate454// the hash value.455unsigned int hashValue;456if (use_alternate_hashcode()) {457hashValue = hash_symbol(names[i], lengths[i]);458} else {459hashValue = hashValues[i];460}461// Since look-up was done lock-free, we need to check if another462// thread beat us in the race to insert the symbol.463int index = hash_to_index(hashValue);464Symbol* test = lookup(index, names[i], lengths[i], hashValue);465if (test != NULL) {466// A race occurred and another thread introduced the symbol, this one467// will be dropped and collected. Use test instead.468cp->symbol_at_put(cp_indices[i], test);469assert(test->refcount() != 0, "lookup should have incremented the count");470} else {471// Create a new symbol. The null class loader is never unloaded so these472// are allocated specially in a permanent arena.473bool c_heap = !loader_data->is_the_null_class_loader_data();474Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false));475assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized"); // why wouldn't it be???476HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym);477add_entry(index, entry);478cp->symbol_at_put(cp_indices[i], sym);479}480}481return true;482}483484485void SymbolTable::verify() {486for (int i = 0; i < the_table()->table_size(); ++i) {487HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);488for ( ; p != NULL; p = p->next()) {489Symbol* s = (Symbol*)(p->literal());490guarantee(s != NULL, "symbol is NULL");491unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length());492guarantee(p->hash() == h, "broken hash in symbol table entry");493guarantee(the_table()->hash_to_index(h) == i,494"wrong index in symbol table");495}496}497}498499void SymbolTable::dump(outputStream* st) {500the_table()->dump_table(st, "SymbolTable");501}502503504//---------------------------------------------------------------------------505// Non-product code506507#ifndef PRODUCT508509void SymbolTable::print_histogram() {510MutexLocker ml(SymbolTable_lock);511const int results_length = 100;512int results[results_length];513int i,j;514515// initialize results to zero516for (j = 0; j < results_length; j++) {517results[j] = 0;518}519520int total = 0;521int max_symbols = 0;522int out_of_range = 0;523int memory_total = 0;524int count = 0;525for (i = 0; i < the_table()->table_size(); i++) {526HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);527for ( ; p != NULL; p = p->next()) {528memory_total += p->literal()->size();529count++;530int counter = p->literal()->utf8_length();531total += counter;532if (counter < results_length) {533results[counter]++;534} else {535out_of_range++;536}537max_symbols = MAX2(max_symbols, counter);538}539}540tty->print_cr("Symbol Table:");541tty->print_cr("Total number of symbols %5d", count);542tty->print_cr("Total size in memory %5dK",543(memory_total*HeapWordSize)/1024);544tty->print_cr("Total counted %5d", _symbols_counted);545tty->print_cr("Total removed %5d", _symbols_removed);546if (_symbols_counted > 0) {547tty->print_cr("Percent removed %3.2f",548((float)_symbols_removed/(float)_symbols_counted)* 100);549}550tty->print_cr("Reference counts %5d", Symbol::_total_count);551tty->print_cr("Symbol arena size %5d used %5d",552arena()->size_in_bytes(), arena()->used());553tty->print_cr("Histogram of symbol length:");554tty->print_cr("%8s %5d", "Total ", total);555tty->print_cr("%8s %5d", "Maximum", max_symbols);556tty->print_cr("%8s %3.2f", "Average",557((float) total / (float) the_table()->table_size()));558tty->print_cr("%s", "Histogram:");559tty->print_cr(" %s %29s", "Length", "Number chains that length");560for (i = 0; i < results_length; i++) {561if (results[i] > 0) {562tty->print_cr("%6d %10d", i, results[i]);563}564}565if (Verbose) {566int line_length = 70;567tty->print_cr("%s %30s", " Length", "Number chains that length");568for (i = 0; i < results_length; i++) {569if (results[i] > 0) {570tty->print("%4d", i);571for (j = 0; (j < results[i]) && (j < line_length); j++) {572tty->print("%1s", "*");573}574if (j == line_length) {575tty->print("%1s", "+");576}577tty->cr();578}579}580}581tty->print_cr(" %s %d: %d\n", "Number chains longer than",582results_length, out_of_range);583}584585void SymbolTable::print() {586for (int i = 0; i < the_table()->table_size(); ++i) {587HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);588HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);589if (entry != NULL) {590while (entry != NULL) {591tty->print(PTR_FORMAT " ", entry->literal());592entry->literal()->print();593tty->print(" %d", entry->literal()->refcount());594p = entry->next_addr();595entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);596}597tty->cr();598}599}600}601#endif // PRODUCT602603// --------------------------------------------------------------------------604605#ifdef ASSERT606class StableMemoryChecker : public StackObj {607enum { _bufsize = wordSize*4 };608609address _region;610jint _size;611u1 _save_buf[_bufsize];612613int sample(u1* save_buf) {614if (_size <= _bufsize) {615memcpy(save_buf, _region, _size);616return _size;617} else {618// copy head and tail619memcpy(&save_buf[0], _region, _bufsize/2);620memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2);621return (_bufsize/2)*2;622}623}624625public:626StableMemoryChecker(const void* region, jint size) {627_region = (address) region;628_size = size;629sample(_save_buf);630}631632bool verify() {633u1 check_buf[sizeof(_save_buf)];634int check_size = sample(check_buf);635return (0 == memcmp(_save_buf, check_buf, check_size));636}637638void set_region(const void* region) { _region = (address) region; }639};640#endif641642643// --------------------------------------------------------------------------644StringTable* StringTable::_the_table = NULL;645646bool StringTable::_needs_rehashing = false;647648volatile int StringTable::_parallel_claimed_idx = 0;649650// Pick hashing algorithm651unsigned int StringTable::hash_string(const jchar* s, int len) {652return use_alternate_hashcode() ? AltHashing::halfsiphash_32(seed(), s, len) :653java_lang_String::hash_code(s, len);654}655656oop StringTable::lookup(int index, jchar* name,657int len, unsigned int hash) {658int count = 0;659for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {660count++;661if (l->hash() == hash) {662if (java_lang_String::equals(l->literal(), name, len)) {663return l->literal();664}665}666}667// If the bucket size is too deep check if this hash code is insufficient.668if (count >= rehash_count && !needs_rehashing()) {669_needs_rehashing = check_rehash_table(count);670}671return NULL;672}673674675oop StringTable::basic_add(int index_arg, Handle string, jchar* name,676int len, unsigned int hashValue_arg, TRAPS) {677678assert(java_lang_String::equals(string(), name, len),679"string must be properly initialized");680// Cannot hit a safepoint in this function because the "this" pointer can move.681No_Safepoint_Verifier nsv;682683// Check if the symbol table has been rehashed, if so, need to recalculate684// the hash value and index before second lookup.685unsigned int hashValue;686int index;687if (use_alternate_hashcode()) {688hashValue = hash_string(name, len);689index = hash_to_index(hashValue);690} else {691hashValue = hashValue_arg;692index = index_arg;693}694695// Since look-up was done lock-free, we need to check if another696// thread beat us in the race to insert the symbol.697698oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)699if (test != NULL) {700// Entry already added701return test;702}703704HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());705add_entry(index, entry);706return string();707}708709710oop StringTable::lookup(Symbol* symbol) {711ResourceMark rm;712int length;713jchar* chars = symbol->as_unicode(length);714return lookup(chars, length);715}716717// Tell the GC that this string was looked up in the StringTable.718static void ensure_string_alive(oop string) {719// A lookup in the StringTable could return an object that was previously720// considered dead. The SATB part of G1 needs to get notified about this721// potential resurrection, otherwise the marking might not find the object.722#if INCLUDE_ALL_GCS723if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && string != NULL) {724G1SATBCardTableModRefBS::enqueue(string);725}726#endif727}728729oop StringTable::lookup(jchar* name, int len) {730unsigned int hash = hash_string(name, len);731int index = the_table()->hash_to_index(hash);732oop string = the_table()->lookup(index, name, len, hash);733734ensure_string_alive(string);735736return string;737}738739740oop StringTable::intern(Handle string_or_null, jchar* name,741int len, TRAPS) {742unsigned int hashValue = hash_string(name, len);743int index = the_table()->hash_to_index(hashValue);744oop found_string = the_table()->lookup(index, name, len, hashValue);745746// Found747if (found_string != NULL) {748ensure_string_alive(found_string);749return found_string;750}751752debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));753assert(!Universe::heap()->is_in_reserved(name),754"proposed name of symbol must be stable");755756Handle string;757// try to reuse the string if possible758if (!string_or_null.is_null()) {759string = string_or_null;760} else {761string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);762}763764#if INCLUDE_ALL_GCS765if (G1StringDedup::is_enabled()) {766// Deduplicate the string before it is interned. Note that we should never767// deduplicate a string after it has been interned. Doing so will counteract768// compiler optimizations done on e.g. interned string literals.769G1StringDedup::deduplicate(string());770}771#endif772773// Grab the StringTable_lock before getting the_table() because it could774// change at safepoint.775oop added_or_found;776{777MutexLocker ml(StringTable_lock, THREAD);778// Otherwise, add to symbol to table779added_or_found = the_table()->basic_add(index, string, name, len,780hashValue, CHECK_NULL);781}782783ensure_string_alive(added_or_found);784785return added_or_found;786}787788oop StringTable::intern(Symbol* symbol, TRAPS) {789if (symbol == NULL) return NULL;790ResourceMark rm(THREAD);791int length;792jchar* chars = symbol->as_unicode(length);793Handle string;794oop result = intern(string, chars, length, CHECK_NULL);795return result;796}797798799oop StringTable::intern(oop string, TRAPS)800{801if (string == NULL) return NULL;802ResourceMark rm(THREAD);803int length;804Handle h_string (THREAD, string);805jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);806oop result = intern(h_string, chars, length, CHECK_NULL);807return result;808}809810811oop StringTable::intern(const char* utf8_string, TRAPS) {812if (utf8_string == NULL) return NULL;813ResourceMark rm(THREAD);814int length = UTF8::unicode_length(utf8_string);815jchar* chars = NEW_RESOURCE_ARRAY(jchar, length);816UTF8::convert_to_unicode(utf8_string, chars, length);817Handle string;818oop result = intern(string, chars, length, CHECK_NULL);819return result;820}821822void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {823BucketUnlinkContext context;824buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), &context);825_the_table->bulk_free_entries(&context);826*processed = context._num_processed;827*removed = context._num_removed;828}829830void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {831// Readers of the table are unlocked, so we should only be removing832// entries at a safepoint.833assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");834const int limit = the_table()->table_size();835836BucketUnlinkContext context;837for (;;) {838// Grab next set of buckets to scan839int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;840if (start_idx >= limit) {841// End of table842break;843}844845int end_idx = MIN2(limit, start_idx + ClaimChunkSize);846buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, &context);847}848_the_table->bulk_free_entries(&context);849*processed = context._num_processed;850*removed = context._num_removed;851}852853void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {854const int limit = the_table()->table_size();855856assert(0 <= start_idx && start_idx <= limit,857err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));858assert(0 <= end_idx && end_idx <= limit,859err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));860assert(start_idx <= end_idx,861err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,862start_idx, end_idx));863864for (int i = start_idx; i < end_idx; i += 1) {865HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);866while (entry != NULL) {867assert(!entry->is_shared(), "CDS not used for the StringTable");868869f->do_oop((oop*)entry->literal_addr());870871entry = entry->next();872}873}874}875876void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, BucketUnlinkContext* context) {877const int limit = the_table()->table_size();878879assert(0 <= start_idx && start_idx <= limit,880err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx));881assert(0 <= end_idx && end_idx <= limit,882err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx));883assert(start_idx <= end_idx,884err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,885start_idx, end_idx));886887for (int i = start_idx; i < end_idx; ++i) {888HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);889HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);890while (entry != NULL) {891assert(!entry->is_shared(), "CDS not used for the StringTable");892893if (is_alive->do_object_b(entry->literal())) {894if (f != NULL) {895f->do_oop((oop*)entry->literal_addr());896}897p = entry->next_addr();898} else {899*p = entry->next();900context->free_entry(entry);901}902context->_num_processed++;903entry = *p;904}905}906}907908void StringTable::oops_do(OopClosure* f) {909buckets_oops_do(f, 0, the_table()->table_size());910}911912void StringTable::possibly_parallel_oops_do(OopClosure* f) {913const int limit = the_table()->table_size();914915for (;;) {916// Grab next set of buckets to scan917int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;918if (start_idx >= limit) {919// End of table920break;921}922923int end_idx = MIN2(limit, start_idx + ClaimChunkSize);924buckets_oops_do(f, start_idx, end_idx);925}926}927928void StringTable::possibly_parallel_oops_do_shenandoah(OopClosure* f) {929const int limit = the_table()->table_size();930931// ClaimChunkSize is too small for processing a String table during the pause932// efficiently: the atomic add costs dominate on many reasonable string tables.933// Recast the chunk size to give each GC worker about 10 chunks.934assert(UseShenandoahGC, "Only for Shenandoah");935const int chunk_size = MAX2<int>(ClaimChunkSize, limit / (ParallelGCThreads * 10));936937for (;;) {938// Grab next set of buckets to scan939int start_idx = Atomic::add(chunk_size, &_parallel_claimed_idx) - chunk_size;940if (start_idx >= limit) {941// End of table942break;943}944945int end_idx = MIN2(limit, start_idx + chunk_size);946buckets_oops_do(f, start_idx, end_idx);947}948}949950// This verification is part of Universe::verify() and needs to be quick.951// See StringTable::verify_and_compare() below for exhaustive verification.952void StringTable::verify() {953for (int i = 0; i < the_table()->table_size(); ++i) {954HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);955for ( ; p != NULL; p = p->next()) {956oop s = p->literal();957guarantee(s != NULL, "interned string is NULL");958unsigned int h = java_lang_String::hash_string(s);959guarantee(p->hash() == h, "broken hash in string table entry");960guarantee(the_table()->hash_to_index(h) == i,961"wrong index in string table");962}963}964}965966void StringTable::dump(outputStream* st) {967the_table()->dump_table(st, "StringTable");968}969970StringTable::VerifyRetTypes StringTable::compare_entries(971int bkt1, int e_cnt1,972HashtableEntry<oop, mtSymbol>* e_ptr1,973int bkt2, int e_cnt2,974HashtableEntry<oop, mtSymbol>* e_ptr2) {975// These entries are sanity checked by verify_and_compare_entries()976// before this function is called.977oop str1 = e_ptr1->literal();978oop str2 = e_ptr2->literal();979980if (str1 == str2) {981tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "982"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",983(void *)str1, bkt1, e_cnt1, bkt2, e_cnt2);984return _verify_fail_continue;985}986987if (java_lang_String::equals(str1, str2)) {988tty->print_cr("ERROR: identical String values in entry @ "989"bucket[%d][%d] and entry @ bucket[%d][%d]",990bkt1, e_cnt1, bkt2, e_cnt2);991return _verify_fail_continue;992}993994return _verify_pass;995}996997StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,998HashtableEntry<oop, mtSymbol>* e_ptr,999StringTable::VerifyMesgModes mesg_mode) {10001001VerifyRetTypes ret = _verify_pass; // be optimistic10021003oop str = e_ptr->literal();1004if (str == NULL) {1005if (mesg_mode == _verify_with_mesgs) {1006tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt,1007e_cnt);1008}1009// NULL oop means no more verifications are possible1010return _verify_fail_done;1011}10121013if (str->klass() != SystemDictionary::String_klass()) {1014if (mesg_mode == _verify_with_mesgs) {1015tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]",1016bkt, e_cnt);1017}1018// not a String means no more verifications are possible1019return _verify_fail_done;1020}10211022unsigned int h = java_lang_String::hash_string(str);1023if (e_ptr->hash() != h) {1024if (mesg_mode == _verify_with_mesgs) {1025tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "1026"bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h);1027}1028ret = _verify_fail_continue;1029}10301031if (the_table()->hash_to_index(h) != bkt) {1032if (mesg_mode == _verify_with_mesgs) {1033tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], "1034"str_hash=%d, hash_to_index=%d", bkt, e_cnt, h,1035the_table()->hash_to_index(h));1036}1037ret = _verify_fail_continue;1038}10391040return ret;1041}10421043// See StringTable::verify() above for the quick verification that is1044// part of Universe::verify(). This verification is exhaustive and1045// reports on every issue that is found. StringTable::verify() only1046// reports on the first issue that is found.1047//1048// StringTable::verify_entry() checks:1049// - oop value != NULL (same as verify())1050// - oop value is a String1051// - hash(String) == hash in entry (same as verify())1052// - index for hash == index of entry (same as verify())1053//1054// StringTable::compare_entries() checks:1055// - oops are unique across all entries1056// - String values are unique across all entries1057//1058int StringTable::verify_and_compare_entries() {1059assert(StringTable_lock->is_locked(), "sanity check");10601061int fail_cnt = 0;10621063// first, verify all the entries individually:1064for (int bkt = 0; bkt < the_table()->table_size(); bkt++) {1065HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt);1066for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) {1067VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs);1068if (ret != _verify_pass) {1069fail_cnt++;1070}1071}1072}10731074// Optimization: if the above check did not find any failures, then1075// the comparison loop below does not need to call verify_entry()1076// before calling compare_entries(). If there were failures, then we1077// have to call verify_entry() to see if the entry can be passed to1078// compare_entries() safely. When we call verify_entry() in the loop1079// below, we do so quietly to void duplicate messages and we don't1080// increment fail_cnt because the failures have already been counted.1081bool need_entry_verify = (fail_cnt != 0);10821083// second, verify all entries relative to each other:1084for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) {1085HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1);1086for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) {1087if (need_entry_verify) {1088VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1,1089_verify_quietly);1090if (ret == _verify_fail_done) {1091// cannot use the current entry to compare against other entries1092continue;1093}1094}10951096for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) {1097HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2);1098int e_cnt2;1099for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) {1100if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) {1101// skip the entries up to and including the one that1102// we're comparing against1103continue;1104}11051106if (need_entry_verify) {1107VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2,1108_verify_quietly);1109if (ret == _verify_fail_done) {1110// cannot compare against this entry1111continue;1112}1113}11141115// compare two entries, report and count any failures:1116if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2)1117!= _verify_pass) {1118fail_cnt++;1119}1120}1121}1122}1123}1124return fail_cnt;1125}11261127// Create a new table and using alternate hash code, populate the new table1128// with the existing strings. Set flag to use the alternate hash code afterwards.1129void StringTable::rehash_table() {1130assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");1131// This should never happen with -Xshare:dump but it might in testing mode.1132if (DumpSharedSpaces) return;1133StringTable* new_table = new StringTable();11341135// Rehash the table1136the_table()->move_to(new_table);11371138// Delete the table and buckets (entries are reused in new table).1139delete _the_table;1140// Don't check if we need rehashing until the table gets unbalanced again.1141// Then rehash with a new global seed.1142_needs_rehashing = false;1143_the_table = new_table;1144}114511461147