src/share/vm/classfile/symbolTable.cpp

changeset 3875
246d977b51f2
parent 3865
e9140bf80b4a
child 3900
d2a62e0f25eb
     1.1 --- a/src/share/vm/classfile/symbolTable.cpp	Fri Jun 22 15:39:16 2012 -0700
     1.2 +++ b/src/share/vm/classfile/symbolTable.cpp	Mon Jun 25 21:33:35 2012 -0400
     1.3 @@ -46,11 +46,8 @@
     1.4  jint SymbolTable::_seed = 0;
     1.5  
     1.6  Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
     1.7 -  // Don't allow symbols to be created which cannot fit in a Symbol*.
     1.8 -  if (len > Symbol::max_length()) {
     1.9 -    THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    1.10 -                "name is too long to represent");
    1.11 -  }
    1.12 +  assert (len <= Symbol::max_length(), "should be checked by caller");
    1.13 +
    1.14    Symbol* sym;
    1.15    // Allocate symbols in the C heap when dumping shared spaces in case there
    1.16    // are temporary symbols we can remove.
    1.17 @@ -95,9 +92,14 @@
    1.18    int total = 0;
    1.19    size_t memory_total = 0;
    1.20    for (int i = 0; i < the_table()->table_size(); ++i) {
    1.21 -    for (HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) {
    1.22 -      HashtableEntry<Symbol*>* entry = *p;
    1.23 -      if (entry->is_shared()) {
    1.24 +    HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i);
    1.25 +    HashtableEntry<Symbol*>* entry = the_table()->bucket(i);
    1.26 +    while (entry != NULL) {
    1.27 +      // Shared entries are normally at the end of the bucket and if we run into
    1.28 +      // a shared entry, then there is nothing more to remove. However, if we
    1.29 +      // have rehashed the table, then the shared entries are no longer at the
    1.30 +      // end of the bucket.
    1.31 +      if (entry->is_shared() && !use_alternate_hashcode()) {
    1.32          break;
    1.33        }
    1.34        Symbol* s = entry->literal();
    1.35 @@ -106,6 +108,7 @@
    1.36        assert(s != NULL, "just checking");
    1.37        // If reference count is zero, remove.
    1.38        if (s->refcount() == 0) {
    1.39 +        assert(!entry->is_shared(), "shared entries should be kept live");
    1.40          delete s;
    1.41          removed++;
    1.42          *p = entry->next();
    1.43 @@ -113,6 +116,8 @@
    1.44        } else {
    1.45          p = entry->next_addr();
    1.46        }
    1.47 +      // get next entry
    1.48 +      entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p);
    1.49      }
    1.50    }
    1.51    symbols_removed += removed;
    1.52 @@ -135,7 +140,8 @@
    1.53  // with the existing strings.   Set flag to use the alternate hash code afterwards.
    1.54  void SymbolTable::rehash_table() {
    1.55    assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
    1.56 -  assert(!DumpSharedSpaces, "this should never happen with -Xshare:dump");
    1.57 +  // This should never happen with -Xshare:dump but it might in testing mode.
    1.58 +  if (DumpSharedSpaces) return;
    1.59    // Create a new symbol table
    1.60    SymbolTable* new_table = new SymbolTable();
    1.61  
    1.62 @@ -176,12 +182,11 @@
    1.63    return NULL;
    1.64  }
    1.65  
    1.66 -// Pick hashing algorithm, but return value already given if not using a new
    1.67 -// hash algorithm.
    1.68 -unsigned int SymbolTable::hash_symbol(const char* s, int len, unsigned int hashValue) {
    1.69 +// Pick hashing algorithm.
    1.70 +unsigned int SymbolTable::hash_symbol(const char* s, int len) {
    1.71    return use_alternate_hashcode() ?
    1.72             AltHashing::murmur3_32(seed(), (const jbyte*)s, len) :
    1.73 -           (hashValue != 0 ? hashValue : java_lang_String::to_hash(s, len));
    1.74 +           java_lang_String::to_hash(s, len);
    1.75  }
    1.76  
    1.77  
    1.78 @@ -201,6 +206,9 @@
    1.79    // Found
    1.80    if (s != NULL) return s;
    1.81  
    1.82 +  // Grab SymbolTable_lock first.
    1.83 +  MutexLocker ml(SymbolTable_lock, THREAD);
    1.84 +
    1.85    // Otherwise, add to symbol to table
    1.86    return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL);
    1.87  }
    1.88 @@ -238,6 +246,9 @@
    1.89    // We can't include the code in No_Safepoint_Verifier because of the
    1.90    // ResourceMark.
    1.91  
    1.92 +  // Grab SymbolTable_lock first.
    1.93 +  MutexLocker ml(SymbolTable_lock, THREAD);
    1.94 +
    1.95    return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL);
    1.96  }
    1.97  
    1.98 @@ -306,6 +317,9 @@
    1.99                        int names_count,
   1.100                        const char** names, int* lengths, int* cp_indices,
   1.101                        unsigned int* hashValues, TRAPS) {
   1.102 +  // Grab SymbolTable_lock first.
   1.103 +  MutexLocker ml(SymbolTable_lock, THREAD);
   1.104 +
   1.105    SymbolTable* table = the_table();
   1.106    bool added = table->basic_add(class_loader, cp, names_count, names, lengths,
   1.107                                  cp_indices, hashValues, CHECK);
   1.108 @@ -326,22 +340,39 @@
   1.109    if (result != NULL) {
   1.110      return result;
   1.111    }
   1.112 +  // Grab SymbolTable_lock first.
   1.113 +  MutexLocker ml(SymbolTable_lock, THREAD);
   1.114 +
   1.115    SymbolTable* table = the_table();
   1.116    int index = table->hash_to_index(hash);
   1.117    return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);
   1.118  }
   1.119  
   1.120 -Symbol* SymbolTable::basic_add(int index, u1 *name, int len,
   1.121 +Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len,
   1.122                                 unsigned int hashValue_arg, bool c_heap, TRAPS) {
   1.123    assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   1.124           "proposed name of symbol must be stable");
   1.125  
   1.126 -  // Grab SymbolTable_lock first.
   1.127 -  MutexLocker ml(SymbolTable_lock, THREAD);
   1.128 +  // Don't allow symbols to be created which cannot fit in a Symbol*.
   1.129 +  if (len > Symbol::max_length()) {
   1.130 +    THROW_MSG_0(vmSymbols::java_lang_InternalError(),
   1.131 +                "name is too long to represent");
   1.132 +  }
   1.133 +
   1.134 +  // Cannot hit a safepoint in this function because the "this" pointer can move.
   1.135 +  No_Safepoint_Verifier nsv;
   1.136  
   1.137    // Check if the symbol table has been rehashed, if so, need to recalculate
   1.138 -  // the hash value.
   1.139 -  unsigned int hashValue = hash_symbol((const char*)name, len, hashValue_arg);
   1.140 +  // the hash value and index.
   1.141 +  unsigned int hashValue;
   1.142 +  int index;
   1.143 +  if (use_alternate_hashcode()) {
   1.144 +    hashValue = hash_symbol((const char*)name, len);
   1.145 +    index = hash_to_index(hashValue);
   1.146 +  } else {
   1.147 +    hashValue = hashValue_arg;
   1.148 +    index = index_arg;
   1.149 +  }
   1.150  
   1.151    // Since look-up was done lock-free, we need to check if another
   1.152    // thread beat us in the race to insert the symbol.
   1.153 @@ -377,13 +408,18 @@
   1.154      }
   1.155    }
   1.156  
   1.157 -  // Hold SymbolTable_lock through the symbol creation
   1.158 -  MutexLocker ml(SymbolTable_lock, THREAD);
   1.159 +  // Cannot hit a safepoint in this function because the "this" pointer can move.
   1.160 +  No_Safepoint_Verifier nsv;
   1.161  
   1.162    for (int i=0; i<names_count; i++) {
   1.163      // Check if the symbol table has been rehashed, if so, need to recalculate
   1.164      // the hash value.
   1.165 -    unsigned int hashValue = hash_symbol(names[i], lengths[i], hashValues[i]);
   1.166 +    unsigned int hashValue;
   1.167 +    if (use_alternate_hashcode()) {
   1.168 +      hashValue = hash_symbol(names[i], lengths[i]);
   1.169 +    } else {
   1.170 +      hashValue = hashValues[i];
   1.171 +    }
   1.172      // Since look-up was done lock-free, we need to check if another
   1.173      // thread beat us in the race to insert the symbol.
   1.174      int index = hash_to_index(hashValue);
   1.175 @@ -587,9 +623,9 @@
   1.176  jint StringTable::_seed = 0;
   1.177  
   1.178  // Pick hashing algorithm
   1.179 -unsigned int StringTable::hash_string(const jchar* s, int len, unsigned int hashValue) {
   1.180 +unsigned int StringTable::hash_string(const jchar* s, int len) {
   1.181    return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
   1.182 -            (hashValue != 0 ? hashValue : java_lang_String::to_hash(s, len));
   1.183 +                                    java_lang_String::to_hash(s, len);
   1.184  }
   1.185  
   1.186  oop StringTable::lookup(int index, jchar* name,
   1.187 @@ -611,29 +647,25 @@
   1.188  }
   1.189  
   1.190  
   1.191 -oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
   1.192 +oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
   1.193                             int len, unsigned int hashValue_arg, TRAPS) {
   1.194 -  debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
   1.195 -  assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   1.196 -         "proposed name of symbol must be stable");
   1.197 -
   1.198 -  Handle string;
   1.199 -  // try to reuse the string if possible
   1.200 -  if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
   1.201 -    string = string_or_null;
   1.202 -  } else {
   1.203 -    string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
   1.204 -  }
   1.205 -
   1.206 -  // Allocation must be done before grapping the SymbolTable_lock lock
   1.207 -  MutexLocker ml(StringTable_lock, THREAD);
   1.208  
   1.209    assert(java_lang_String::equals(string(), name, len),
   1.210           "string must be properly initialized");
   1.211 +  // Cannot hit a safepoint in this function because the "this" pointer can move.
   1.212 +  No_Safepoint_Verifier nsv;
   1.213  
   1.214    // Check if the symbol table has been rehashed, if so, need to recalculate
   1.215 -  // the hash value before second lookup.
   1.216 -  unsigned int hashValue = hash_string(name, len, hashValue_arg);
   1.217 +  // the hash value and index before second lookup.
   1.218 +  unsigned int hashValue;
   1.219 +  int index;
   1.220 +  if (use_alternate_hashcode()) {
   1.221 +    hashValue = hash_string(name, len);
   1.222 +    index = hash_to_index(hashValue);
   1.223 +  } else {
   1.224 +    hashValue = hashValue_arg;
   1.225 +    index = index_arg;
   1.226 +  }
   1.227  
   1.228    // Since look-up was done lock-free, we need to check if another
   1.229    // thread beat us in the race to insert the symbol.
   1.230 @@ -664,13 +696,29 @@
   1.231                          int len, TRAPS) {
   1.232    unsigned int hashValue = hash_string(name, len);
   1.233    int index = the_table()->hash_to_index(hashValue);
   1.234 -  oop string = the_table()->lookup(index, name, len, hashValue);
   1.235 +  oop found_string = the_table()->lookup(index, name, len, hashValue);
   1.236  
   1.237    // Found
   1.238 -  if (string != NULL) return string;
   1.239 +  if (found_string != NULL) return found_string;
   1.240 +
   1.241 +  debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
   1.242 +  assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   1.243 +         "proposed name of symbol must be stable");
   1.244 +
   1.245 +  Handle string;
   1.246 +  // try to reuse the string if possible
   1.247 +  if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
   1.248 +    string = string_or_null;
   1.249 +  } else {
   1.250 +    string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
   1.251 +  }
   1.252 +
   1.253 +  // Grab the StringTable_lock before getting the_table() because it could
   1.254 +  // change at safepoint.
   1.255 +  MutexLocker ml(StringTable_lock, THREAD);
   1.256  
   1.257    // Otherwise, add to symbol to table
   1.258 -  return the_table()->basic_add(index, string_or_null, name, len,
   1.259 +  return the_table()->basic_add(index, string, name, len,
   1.260                                  hashValue, CHECK_NULL);
   1.261  }
   1.262  
   1.263 @@ -713,18 +761,24 @@
   1.264    // entries at a safepoint.
   1.265    assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   1.266    for (int i = 0; i < the_table()->table_size(); ++i) {
   1.267 -    for (HashtableEntry<oop>** p = the_table()->bucket_addr(i); *p != NULL; ) {
   1.268 -      HashtableEntry<oop>* entry = *p;
   1.269 -      if (entry->is_shared()) {
   1.270 +    HashtableEntry<oop>** p = the_table()->bucket_addr(i);
   1.271 +    HashtableEntry<oop>* entry = the_table()->bucket(i);
   1.272 +    while (entry != NULL) {
   1.273 +      // Shared entries are normally at the end of the bucket and if we run into
   1.274 +      // a shared entry, then there is nothing more to remove. However, if we
   1.275 +      // have rehashed the table, then the shared entries are no longer at the
   1.276 +      // end of the bucket.
   1.277 +      if (entry->is_shared() && !use_alternate_hashcode()) {
   1.278          break;
   1.279        }
   1.280        assert(entry->literal() != NULL, "just checking");
   1.281 -      if (is_alive->do_object_b(entry->literal())) {
   1.282 +      if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
   1.283          p = entry->next_addr();
   1.284        } else {
   1.285          *p = entry->next();
   1.286          the_table()->free_entry(entry);
   1.287        }
   1.288 +      entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p);
   1.289      }
   1.290    }
   1.291  }
   1.292 @@ -795,7 +849,8 @@
   1.293  // with the existing strings.   Set flag to use the alternate hash code afterwards.
   1.294  void StringTable::rehash_table() {
   1.295    assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   1.296 -  assert(!DumpSharedSpaces, "this should never happen with -Xshare:dump");
   1.297 +  // This should never happen with -Xshare:dump but it might in testing mode.
   1.298 +  if (DumpSharedSpaces) return;
   1.299    StringTable* new_table = new StringTable();
   1.300  
   1.301    // Initialize new global seed for hashing.

mercurial