src/share/vm/classfile/symbolTable.cpp

Fri, 23 Mar 2012 11:16:05 -0400

author
coleenp
date
Fri, 23 Mar 2012 11:16:05 -0400
changeset 3682
fc9d8850ab8b
parent 3427
94ec88ca68e2
child 3865
e9140bf80b4a
permissions
-rw-r--r--

7150058: Allocate symbols from null boot loader to an arena for NMT
Summary: Move symbol allocation to an arena so NMT doesn't have to track them at startup.
Reviewed-by: never, kamg, zgu

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.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"
    38 // --------------------------------------------------------------------------
    40 SymbolTable* SymbolTable::_the_table = NULL;
    41 // Static arena for symbols that are not deallocated
    42 Arena* SymbolTable::_arena = NULL;
    44 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
    45   // Don't allow symbols to be created which cannot fit in a Symbol*.
    46   if (len > Symbol::max_length()) {
    47     THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    48                 "name is too long to represent");
    49   }
    50   Symbol* sym;
    51   // Allocate symbols in the C heap when dumping shared spaces in case there
    52   // are temporary symbols we can remove.
    53   if (c_heap || DumpSharedSpaces) {
    54     // refcount starts as 1
    55     sym = new (len, THREAD) Symbol(name, len, 1);
    56   } else {
    57     sym = new (len, arena(), THREAD) Symbol(name, len, -1);
    58   }
    59   assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
    60   return sym;
    61 }
    63 void SymbolTable::initialize_symbols(int arena_alloc_size) {
    64   // Initialize the arena for global symbols, size passed in depends on CDS.
    65   if (arena_alloc_size == 0) {
    66     _arena = new Arena();
    67   } else {
    68     _arena = new Arena(arena_alloc_size);
    69   }
    70 }
    72 // Call function for all symbols in the symbol table.
    73 void SymbolTable::symbols_do(SymbolClosure *cl) {
    74   const int n = the_table()->table_size();
    75   for (int i = 0; i < n; i++) {
    76     for (HashtableEntry<Symbol*>* p = the_table()->bucket(i);
    77          p != NULL;
    78          p = p->next()) {
    79       cl->do_symbol(p->literal_addr());
    80     }
    81   }
    82 }
    84 int SymbolTable::symbols_removed = 0;
    85 int SymbolTable::symbols_counted = 0;
    87 // Remove unreferenced symbols from the symbol table
    88 // This is done late during GC.
    89 void SymbolTable::unlink() {
    90   int removed = 0;
    91   int total = 0;
    92   size_t memory_total = 0;
    93   for (int i = 0; i < the_table()->table_size(); ++i) {
    94     for (HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) {
    95       HashtableEntry<Symbol*>* entry = *p;
    96       if (entry->is_shared()) {
    97         break;
    98       }
    99       Symbol* s = entry->literal();
   100       memory_total += s->object_size();
   101       total++;
   102       assert(s != NULL, "just checking");
   103       // If reference count is zero, remove.
   104       if (s->refcount() == 0) {
   105         delete s;
   106         removed++;
   107         *p = entry->next();
   108         the_table()->free_entry(entry);
   109       } else {
   110         p = entry->next_addr();
   111       }
   112     }
   113   }
   114   symbols_removed += removed;
   115   symbols_counted += total;
   116   // Exclude printing for normal PrintGCDetails because people parse
   117   // this output.
   118   if (PrintGCDetails && Verbose && WizardMode) {
   119     gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", total,
   120                         (memory_total*HeapWordSize)/1024);
   121   }
   122 }
   125 // Lookup a symbol in a bucket.
   127 Symbol* SymbolTable::lookup(int index, const char* name,
   128                               int len, unsigned int hash) {
   129   for (HashtableEntry<Symbol*>* e = bucket(index); e != NULL; e = e->next()) {
   130     if (e->hash() == hash) {
   131       Symbol* sym = e->literal();
   132       if (sym->equals(name, len)) {
   133         // something is referencing this symbol now.
   134         sym->increment_refcount();
   135         return sym;
   136       }
   137     }
   138   }
   139   return NULL;
   140 }
   143 // We take care not to be blocking while holding the
   144 // SymbolTable_lock. Otherwise, the system might deadlock, since the
   145 // symboltable is used during compilation (VM_thread) The lock free
   146 // synchronization is simplified by the fact that we do not delete
   147 // entries in the symbol table during normal execution (only during
   148 // safepoints).
   150 Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
   151   unsigned int hashValue = hash_symbol(name, len);
   152   int index = the_table()->hash_to_index(hashValue);
   154   Symbol* s = the_table()->lookup(index, name, len, hashValue);
   156   // Found
   157   if (s != NULL) return s;
   159   // Otherwise, add to symbol to table
   160   return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL);
   161 }
   163 Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
   164   char* buffer;
   165   int index, len;
   166   unsigned int hashValue;
   167   char* name;
   168   {
   169     debug_only(No_Safepoint_Verifier nsv;)
   171     name = (char*)sym->base() + begin;
   172     len = end - begin;
   173     hashValue = hash_symbol(name, len);
   174     index = the_table()->hash_to_index(hashValue);
   175     Symbol* s = the_table()->lookup(index, name, len, hashValue);
   177     // Found
   178     if (s != NULL) return s;
   179   }
   181   // Otherwise, add to symbol to table. Copy to a C string first.
   182   char stack_buf[128];
   183   ResourceMark rm(THREAD);
   184   if (len <= 128) {
   185     buffer = stack_buf;
   186   } else {
   187     buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
   188   }
   189   for (int i=0; i<len; i++) {
   190     buffer[i] = name[i];
   191   }
   192   // Make sure there is no safepoint in the code above since name can't move.
   193   // We can't include the code in No_Safepoint_Verifier because of the
   194   // ResourceMark.
   196   return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL);
   197 }
   199 Symbol* SymbolTable::lookup_only(const char* name, int len,
   200                                    unsigned int& hash) {
   201   hash = hash_symbol(name, len);
   202   int index = the_table()->hash_to_index(hash);
   204   Symbol* s = the_table()->lookup(index, name, len, hash);
   205   return s;
   206 }
   208 // Look up the address of the literal in the SymbolTable for this Symbol*
   209 // Do not create any new symbols
   210 // Do not increment the reference count to keep this alive
   211 Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){
   212   unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length());
   213   int index = the_table()->hash_to_index(hash);
   215   for (HashtableEntry<Symbol*>* e = the_table()->bucket(index); e != NULL; e = e->next()) {
   216     if (e->hash() == hash) {
   217       Symbol* literal_sym = e->literal();
   218       if (sym == literal_sym) {
   219         return e->literal_addr();
   220       }
   221     }
   222   }
   223   return NULL;
   224 }
   226 // Suggestion: Push unicode-based lookup all the way into the hashing
   227 // and probing logic, so there is no need for convert_to_utf8 until
   228 // an actual new Symbol* is created.
   229 Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
   230   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   231   char stack_buf[128];
   232   if (utf8_length < (int) sizeof(stack_buf)) {
   233     char* chars = stack_buf;
   234     UNICODE::convert_to_utf8(name, utf16_length, chars);
   235     return lookup(chars, utf8_length, THREAD);
   236   } else {
   237     ResourceMark rm(THREAD);
   238     char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
   239     UNICODE::convert_to_utf8(name, utf16_length, chars);
   240     return lookup(chars, utf8_length, THREAD);
   241   }
   242 }
   244 Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
   245                                            unsigned int& hash) {
   246   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   247   char stack_buf[128];
   248   if (utf8_length < (int) sizeof(stack_buf)) {
   249     char* chars = stack_buf;
   250     UNICODE::convert_to_utf8(name, utf16_length, chars);
   251     return lookup_only(chars, utf8_length, hash);
   252   } else {
   253     ResourceMark rm;
   254     char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
   255     UNICODE::convert_to_utf8(name, utf16_length, chars);
   256     return lookup_only(chars, utf8_length, hash);
   257   }
   258 }
   260 void SymbolTable::add(Handle class_loader, constantPoolHandle cp,
   261                       int names_count,
   262                       const char** names, int* lengths, int* cp_indices,
   263                       unsigned int* hashValues, TRAPS) {
   264   SymbolTable* table = the_table();
   265   bool added = table->basic_add(class_loader, cp, names_count, names, lengths,
   266                                 cp_indices, hashValues, CHECK);
   267   if (!added) {
   268     // do it the hard way
   269     for (int i=0; i<names_count; i++) {
   270       int index = table->hash_to_index(hashValues[i]);
   271       bool c_heap = class_loader() != NULL;
   272       Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], c_heap, CHECK);
   273       cp->symbol_at_put(cp_indices[i], sym);
   274     }
   275   }
   276 }
   278 Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
   279   unsigned int hash;
   280   Symbol* result = SymbolTable::lookup_only((char*)name, (int)strlen(name), hash);
   281   if (result != NULL) {
   282     return result;
   283   }
   284   SymbolTable* table = the_table();
   285   int index = table->hash_to_index(hash);
   286   return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);
   287 }
   289 Symbol* SymbolTable::basic_add(int index, u1 *name, int len,
   290                                unsigned int hashValue, bool c_heap, TRAPS) {
   291   assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   292          "proposed name of symbol must be stable");
   294   // Grab SymbolTable_lock first.
   295   MutexLocker ml(SymbolTable_lock, THREAD);
   297   // Since look-up was done lock-free, we need to check if another
   298   // thread beat us in the race to insert the symbol.
   299   Symbol* test = lookup(index, (char*)name, len, hashValue);
   300   if (test != NULL) {
   301     // A race occurred and another thread introduced the symbol.
   302     assert(test->refcount() != 0, "lookup should have incremented the count");
   303     return test;
   304   }
   306   // Create a new symbol.
   307   Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL);
   308   assert(sym->equals((char*)name, len), "symbol must be properly initialized");
   310   HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
   311   add_entry(index, entry);
   312   return sym;
   313 }
   315 // This version of basic_add adds symbols in batch from the constant pool
   316 // parsing.
   317 bool SymbolTable::basic_add(Handle class_loader, constantPoolHandle cp,
   318                             int names_count,
   319                             const char** names, int* lengths,
   320                             int* cp_indices, unsigned int* hashValues,
   321                             TRAPS) {
   323   // Check symbol names are not too long.  If any are too long, don't add any.
   324   for (int i = 0; i< names_count; i++) {
   325     if (lengths[i] > Symbol::max_length()) {
   326       THROW_MSG_0(vmSymbols::java_lang_InternalError(),
   327                   "name is too long to represent");
   328     }
   329   }
   331   // Hold SymbolTable_lock through the symbol creation
   332   MutexLocker ml(SymbolTable_lock, THREAD);
   334   for (int i=0; i<names_count; i++) {
   335     // Since look-up was done lock-free, we need to check if another
   336     // thread beat us in the race to insert the symbol.
   337     int index = hash_to_index(hashValues[i]);
   338     Symbol* test = lookup(index, names[i], lengths[i], hashValues[i]);
   339     if (test != NULL) {
   340       // A race occurred and another thread introduced the symbol, this one
   341       // will be dropped and collected. Use test instead.
   342       cp->symbol_at_put(cp_indices[i], test);
   343       assert(test->refcount() != 0, "lookup should have incremented the count");
   344     } else {
   345       // Create a new symbol.  The null class loader is never unloaded so these
   346       // are allocated specially in a permanent arena.
   347       bool c_heap = class_loader() != NULL;
   348       Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false));
   349       assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized");  // why wouldn't it be???
   350       HashtableEntry<Symbol*>* entry = new_entry(hashValues[i], sym);
   351       add_entry(index, entry);
   352       cp->symbol_at_put(cp_indices[i], sym);
   353     }
   354   }
   355   return true;
   356 }
   359 void SymbolTable::verify() {
   360   for (int i = 0; i < the_table()->table_size(); ++i) {
   361     HashtableEntry<Symbol*>* p = the_table()->bucket(i);
   362     for ( ; p != NULL; p = p->next()) {
   363       Symbol* s = (Symbol*)(p->literal());
   364       guarantee(s != NULL, "symbol is NULL");
   365       unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length());
   366       guarantee(p->hash() == h, "broken hash in symbol table entry");
   367       guarantee(the_table()->hash_to_index(h) == i,
   368                 "wrong index in symbol table");
   369     }
   370   }
   371 }
   374 //---------------------------------------------------------------------------
   375 // Non-product code
   377 #ifndef PRODUCT
   379 void SymbolTable::print_histogram() {
   380   MutexLocker ml(SymbolTable_lock);
   381   const int results_length = 100;
   382   int results[results_length];
   383   int i,j;
   385   // initialize results to zero
   386   for (j = 0; j < results_length; j++) {
   387     results[j] = 0;
   388   }
   390   int total = 0;
   391   int max_symbols = 0;
   392   int out_of_range = 0;
   393   int memory_total = 0;
   394   int count = 0;
   395   for (i = 0; i < the_table()->table_size(); i++) {
   396     HashtableEntry<Symbol*>* p = the_table()->bucket(i);
   397     for ( ; p != NULL; p = p->next()) {
   398       memory_total += p->literal()->object_size();
   399       count++;
   400       int counter = p->literal()->utf8_length();
   401       total += counter;
   402       if (counter < results_length) {
   403         results[counter]++;
   404       } else {
   405         out_of_range++;
   406       }
   407       max_symbols = MAX2(max_symbols, counter);
   408     }
   409   }
   410   tty->print_cr("Symbol Table:");
   411   tty->print_cr("Total number of symbols  %5d", count);
   412   tty->print_cr("Total size in memory     %5dK",
   413           (memory_total*HeapWordSize)/1024);
   414   tty->print_cr("Total counted            %5d", symbols_counted);
   415   tty->print_cr("Total removed            %5d", symbols_removed);
   416   if (symbols_counted > 0) {
   417     tty->print_cr("Percent removed          %3.2f",
   418           ((float)symbols_removed/(float)symbols_counted)* 100);
   419   }
   420   tty->print_cr("Reference counts         %5d", Symbol::_total_count);
   421   tty->print_cr("Symbol arena size        %5d used %5d",
   422                  arena()->size_in_bytes(), arena()->used());
   423   tty->print_cr("Histogram of symbol length:");
   424   tty->print_cr("%8s %5d", "Total  ", total);
   425   tty->print_cr("%8s %5d", "Maximum", max_symbols);
   426   tty->print_cr("%8s %3.2f", "Average",
   427           ((float) total / (float) the_table()->table_size()));
   428   tty->print_cr("%s", "Histogram:");
   429   tty->print_cr(" %s %29s", "Length", "Number chains that length");
   430   for (i = 0; i < results_length; i++) {
   431     if (results[i] > 0) {
   432       tty->print_cr("%6d %10d", i, results[i]);
   433     }
   434   }
   435   if (Verbose) {
   436     int line_length = 70;
   437     tty->print_cr("%s %30s", " Length", "Number chains that length");
   438     for (i = 0; i < results_length; i++) {
   439       if (results[i] > 0) {
   440         tty->print("%4d", i);
   441         for (j = 0; (j < results[i]) && (j < line_length);  j++) {
   442           tty->print("%1s", "*");
   443         }
   444         if (j == line_length) {
   445           tty->print("%1s", "+");
   446         }
   447         tty->cr();
   448       }
   449     }
   450   }
   451   tty->print_cr(" %s %d: %d\n", "Number chains longer than",
   452                     results_length, out_of_range);
   453 }
   455 void SymbolTable::print() {
   456   for (int i = 0; i < the_table()->table_size(); ++i) {
   457     HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i);
   458     HashtableEntry<Symbol*>* entry = the_table()->bucket(i);
   459     if (entry != NULL) {
   460       while (entry != NULL) {
   461         tty->print(PTR_FORMAT " ", entry->literal());
   462         entry->literal()->print();
   463         tty->print(" %d", entry->literal()->refcount());
   464         p = entry->next_addr();
   465         entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p);
   466       }
   467       tty->cr();
   468     }
   469   }
   470 }
   472 #endif // PRODUCT
   474 // --------------------------------------------------------------------------
   476 #ifdef ASSERT
   477 class StableMemoryChecker : public StackObj {
   478   enum { _bufsize = wordSize*4 };
   480   address _region;
   481   jint    _size;
   482   u1      _save_buf[_bufsize];
   484   int sample(u1* save_buf) {
   485     if (_size <= _bufsize) {
   486       memcpy(save_buf, _region, _size);
   487       return _size;
   488     } else {
   489       // copy head and tail
   490       memcpy(&save_buf[0],          _region,                      _bufsize/2);
   491       memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2);
   492       return (_bufsize/2)*2;
   493     }
   494   }
   496  public:
   497   StableMemoryChecker(const void* region, jint size) {
   498     _region = (address) region;
   499     _size   = size;
   500     sample(_save_buf);
   501   }
   503   bool verify() {
   504     u1 check_buf[sizeof(_save_buf)];
   505     int check_size = sample(check_buf);
   506     return (0 == memcmp(_save_buf, check_buf, check_size));
   507   }
   509   void set_region(const void* region) { _region = (address) region; }
   510 };
   511 #endif
   514 // --------------------------------------------------------------------------
   515 StringTable* StringTable::_the_table = NULL;
   517 oop StringTable::lookup(int index, jchar* name,
   518                         int len, unsigned int hash) {
   519   for (HashtableEntry<oop>* l = bucket(index); l != NULL; l = l->next()) {
   520     if (l->hash() == hash) {
   521       if (java_lang_String::equals(l->literal(), name, len)) {
   522         return l->literal();
   523       }
   524     }
   525   }
   526   return NULL;
   527 }
   530 oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
   531                            int len, unsigned int hashValue, TRAPS) {
   532   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
   533   assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   534          "proposed name of symbol must be stable");
   536   Handle string;
   537   // try to reuse the string if possible
   538   if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
   539     string = string_or_null;
   540   } else {
   541     string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
   542   }
   544   // Allocation must be done before grapping the SymbolTable_lock lock
   545   MutexLocker ml(StringTable_lock, THREAD);
   547   assert(java_lang_String::equals(string(), name, len),
   548          "string must be properly initialized");
   550   // Since look-up was done lock-free, we need to check if another
   551   // thread beat us in the race to insert the symbol.
   553   oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
   554   if (test != NULL) {
   555     // Entry already added
   556     return test;
   557   }
   559   HashtableEntry<oop>* entry = new_entry(hashValue, string());
   560   add_entry(index, entry);
   561   return string();
   562 }
   565 oop StringTable::lookup(Symbol* symbol) {
   566   ResourceMark rm;
   567   int length;
   568   jchar* chars = symbol->as_unicode(length);
   569   unsigned int hashValue = java_lang_String::hash_string(chars, length);
   570   int index = the_table()->hash_to_index(hashValue);
   571   return the_table()->lookup(index, chars, length, hashValue);
   572 }
   575 oop StringTable::intern(Handle string_or_null, jchar* name,
   576                         int len, TRAPS) {
   577   unsigned int hashValue = java_lang_String::hash_string(name, len);
   578   int index = the_table()->hash_to_index(hashValue);
   579   oop string = the_table()->lookup(index, name, len, hashValue);
   581   // Found
   582   if (string != NULL) return string;
   584   // Otherwise, add to symbol to table
   585   return the_table()->basic_add(index, string_or_null, name, len,
   586                                 hashValue, CHECK_NULL);
   587 }
   589 oop StringTable::intern(Symbol* symbol, TRAPS) {
   590   if (symbol == NULL) return NULL;
   591   ResourceMark rm(THREAD);
   592   int length;
   593   jchar* chars = symbol->as_unicode(length);
   594   Handle string;
   595   oop result = intern(string, chars, length, CHECK_NULL);
   596   return result;
   597 }
   600 oop StringTable::intern(oop string, TRAPS)
   601 {
   602   if (string == NULL) return NULL;
   603   ResourceMark rm(THREAD);
   604   int length;
   605   Handle h_string (THREAD, string);
   606   jchar* chars = java_lang_String::as_unicode_string(string, length);
   607   oop result = intern(h_string, chars, length, CHECK_NULL);
   608   return result;
   609 }
   612 oop StringTable::intern(const char* utf8_string, TRAPS) {
   613   if (utf8_string == NULL) return NULL;
   614   ResourceMark rm(THREAD);
   615   int length = UTF8::unicode_length(utf8_string);
   616   jchar* chars = NEW_RESOURCE_ARRAY(jchar, length);
   617   UTF8::convert_to_unicode(utf8_string, chars, length);
   618   Handle string;
   619   oop result = intern(string, chars, length, CHECK_NULL);
   620   return result;
   621 }
   623 void StringTable::unlink(BoolObjectClosure* is_alive) {
   624   // Readers of the table are unlocked, so we should only be removing
   625   // entries at a safepoint.
   626   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   627   for (int i = 0; i < the_table()->table_size(); ++i) {
   628     for (HashtableEntry<oop>** p = the_table()->bucket_addr(i); *p != NULL; ) {
   629       HashtableEntry<oop>* entry = *p;
   630       if (entry->is_shared()) {
   631         break;
   632       }
   633       assert(entry->literal() != NULL, "just checking");
   634       if (is_alive->do_object_b(entry->literal())) {
   635         p = entry->next_addr();
   636       } else {
   637         *p = entry->next();
   638         the_table()->free_entry(entry);
   639       }
   640     }
   641   }
   642 }
   644 void StringTable::oops_do(OopClosure* f) {
   645   for (int i = 0; i < the_table()->table_size(); ++i) {
   646     HashtableEntry<oop>** p = the_table()->bucket_addr(i);
   647     HashtableEntry<oop>* entry = the_table()->bucket(i);
   648     while (entry != NULL) {
   649       f->do_oop((oop*)entry->literal_addr());
   651       // Did the closure remove the literal from the table?
   652       if (entry->literal() == NULL) {
   653         assert(!entry->is_shared(), "immutable hashtable entry?");
   654         *p = entry->next();
   655         the_table()->free_entry(entry);
   656       } else {
   657         p = entry->next_addr();
   658       }
   659       entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p);
   660     }
   661   }
   662 }
   664 void StringTable::verify() {
   665   for (int i = 0; i < the_table()->table_size(); ++i) {
   666     HashtableEntry<oop>* p = the_table()->bucket(i);
   667     for ( ; p != NULL; p = p->next()) {
   668       oop s = p->literal();
   669       guarantee(s != NULL, "interned string is NULL");
   670       guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
   671       unsigned int h = java_lang_String::hash_string(s);
   672       guarantee(p->hash() == h, "broken hash in string table entry");
   673       guarantee(the_table()->hash_to_index(h) == i,
   674                 "wrong index in string table");
   675     }
   676   }
   677 }

mercurial