symbolTable.cpp 21.9 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33 34 35
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/hashtable.inline.hpp"
D
duke 已提交
36 37 38 39 40

// --------------------------------------------------------------------------

SymbolTable* SymbolTable::_the_table = NULL;

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
Symbol* SymbolTable::allocate_symbol(const u1* name, int len, TRAPS) {
  // Don't allow symbols to be created which cannot fit in a Symbol*.
  if (len > Symbol::max_length()) {
    THROW_MSG_0(vmSymbols::java_lang_InternalError(),
                "name is too long to represent");
  }
  Symbol* sym = new (len) Symbol(name, len);
  assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
  return sym;
}

bool SymbolTable::allocate_symbols(int names_count, const u1** names,
                                   int* lengths, Symbol** syms, TRAPS) {
  for (int i = 0; i< names_count; i++) {
    if (lengths[i] > Symbol::max_length()) {
      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
                  "name is too long to represent");
    }
  }

  for (int i = 0; i< names_count; i++) {
    int len = lengths[i];
    syms[i] = new (len) Symbol(names[i], len);
    assert(syms[i] != NULL, "new should call vm_exit_out_of_memory if "
                            "C_HEAP is exhausted");
  }
  return true;
}

// 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*>* p = the_table()->bucket(i);
         p != NULL;
         p = p->next()) {
      cl->do_symbol(p->literal_addr());
    }
  }
}

int SymbolTable::symbols_removed = 0;
int SymbolTable::symbols_counted = 0;

// Remove unreferenced symbols from the symbol table
// This is done late during GC.  This doesn't use the hash table unlink because
// it assumes that the literals are oops.
void SymbolTable::unlink() {
  int removed = 0;
  int total = 0;
91
  size_t memory_total = 0;
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
  for (int i = 0; i < the_table()->table_size(); ++i) {
    for (HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) {
      HashtableEntry<Symbol*>* entry = *p;
      if (entry->is_shared()) {
        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) {
        delete s;
        removed++;
        *p = entry->next();
        the_table()->free_entry(entry);
      } else {
        p = entry->next_addr();
      }
    }
  }
  symbols_removed += removed;
  symbols_counted += total;
115 116 117 118
  // 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,
119 120 121 122 123
                        (memory_total*HeapWordSize)/1024);
  }
}


D
duke 已提交
124 125
// Lookup a symbol in a bucket.

126
Symbol* SymbolTable::lookup(int index, const char* name,
D
duke 已提交
127
                              int len, unsigned int hash) {
128
  for (HashtableEntry<Symbol*>* e = bucket(index); e != NULL; e = e->next()) {
D
duke 已提交
129
    if (e->hash() == hash) {
130
      Symbol* sym = e->literal();
D
duke 已提交
131
      if (sym->equals(name, len)) {
132 133
        // something is referencing this symbol now.
        sym->increment_refcount();
D
duke 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
        return sym;
      }
    }
  }
  return NULL;
}


// We take care not to be blocking while holding the
// SymbolTable_lock. Otherwise, the system might deadlock, since the
// symboltable is used during compilation (VM_thread) The lock free
// synchronization is simplified by the fact that we do not delete
// entries in the symbol table during normal execution (only during
// safepoints).

149
Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
D
duke 已提交
150 151 152
  unsigned int hashValue = hash_symbol(name, len);
  int index = the_table()->hash_to_index(hashValue);

153
  Symbol* s = the_table()->lookup(index, name, len, hashValue);
D
duke 已提交
154 155 156 157 158 159 160 161

  // Found
  if (s != NULL) return s;

  // Otherwise, add to symbol to table
  return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL);
}

162
Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
D
duke 已提交
163 164 165 166 167 168 169 170 171 172 173
  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);
174
    Symbol* s = the_table()->lookup(index, name, len, hashValue);
D
duke 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

    // Found
    if (s != NULL) return s;
  }

  // Otherwise, add to symbol to table. Copy to a C string first.
  char stack_buf[128];
  ResourceMark rm(THREAD);
  if (len <= 128) {
    buffer = stack_buf;
  } else {
    buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
  }
  for (int i=0; i<len; i++) {
    buffer[i] = name[i];
  }
  // Make sure there is no safepoint in the code above since name can't move.
  // We can't include the code in No_Safepoint_Verifier because of the
  // ResourceMark.

  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL);
}

198
Symbol* SymbolTable::lookup_only(const char* name, int len,
D
duke 已提交
199 200 201 202
                                   unsigned int& hash) {
  hash = hash_symbol(name, len);
  int index = the_table()->hash_to_index(hash);

203 204
  Symbol* s = the_table()->lookup(index, name, len, hash);
  return s;
D
duke 已提交
205 206
}

207 208
// Suggestion: Push unicode-based lookup all the way into the hashing
// and probing logic, so there is no need for convert_to_utf8 until
209 210
// an actual new Symbol* is created.
Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
211 212 213 214 215 216 217 218 219 220 221 222 223 224
  int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
  char stack_buf[128];
  if (utf8_length < (int) sizeof(stack_buf)) {
    char* chars = stack_buf;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup(chars, utf8_length, THREAD);
  } else {
    ResourceMark rm(THREAD);
    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup(chars, utf8_length, THREAD);
  }
}

225
Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
                                           unsigned int& hash) {
  int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
  char stack_buf[128];
  if (utf8_length < (int) sizeof(stack_buf)) {
    char* chars = stack_buf;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup_only(chars, utf8_length, hash);
  } else {
    ResourceMark rm;
    char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);;
    UNICODE::convert_to_utf8(name, utf16_length, chars);
    return lookup_only(chars, utf8_length, hash);
  }
}

D
duke 已提交
241 242 243 244 245 246 247 248 249 250
void SymbolTable::add(constantPoolHandle cp, int names_count,
                      const char** names, int* lengths, int* cp_indices,
                      unsigned int* hashValues, TRAPS) {
  SymbolTable* table = the_table();
  bool added = table->basic_add(cp, names_count, names, lengths,
                                cp_indices, hashValues, CHECK);
  if (!added) {
    // do it the hard way
    for (int i=0; i<names_count; i++) {
      int index = table->hash_to_index(hashValues[i]);
251
      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i],
D
duke 已提交
252 253 254 255 256 257
                                       hashValues[i], CHECK);
      cp->symbol_at_put(cp_indices[i], sym);
    }
  }
}

258
Symbol* SymbolTable::basic_add(int index, u1 *name, int len,
D
duke 已提交
259 260 261 262 263 264
                                 unsigned int hashValue, TRAPS) {
  assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
         "proposed name of symbol must be stable");

  // We assume that lookup() has been called already, that it failed,
  // and symbol was not found.  We create the symbol here.
265
  Symbol* sym = allocate_symbol(name, len, CHECK_NULL);
D
duke 已提交
266

267
  // Allocation must be done before grabbing the SymbolTable_lock lock
D
duke 已提交
268 269 270 271 272 273 274
  MutexLocker ml(SymbolTable_lock, THREAD);

  assert(sym->equals((char*)name, len), "symbol must be properly initialized");

  // Since look-up was done lock-free, we need to check if another
  // thread beat us in the race to insert the symbol.

275
  Symbol* test = lookup(index, (char*)name, len, hashValue);
D
duke 已提交
276
  if (test != NULL) {
T
twisti 已提交
277
    // A race occurred and another thread introduced the symbol, this one
D
duke 已提交
278
    // will be dropped and collected.
279 280
    delete sym;
    assert(test->refcount() != 0, "lookup should have incremented the count");
D
duke 已提交
281 282 283
    return test;
  }

284 285
  HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
  sym->increment_refcount();
D
duke 已提交
286
  add_entry(index, entry);
287
  return sym;
D
duke 已提交
288 289 290 291 292 293
}

bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
                            const char** names, int* lengths,
                            int* cp_indices, unsigned int* hashValues,
                            TRAPS) {
294 295 296
  Symbol* syms[symbol_alloc_batch_size];
  bool allocated = allocate_symbols(names_count, (const u1**)names, lengths,
                                    syms, CHECK_false);
D
duke 已提交
297 298 299 300 301 302 303
  if (!allocated) {
    return false;
  }

  // Allocation must be done before grabbing the SymbolTable_lock lock
  MutexLocker ml(SymbolTable_lock, THREAD);

304
  for (int i=0; i<names_count; i++) {
D
duke 已提交
305 306 307 308
    assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized");
    // Since look-up was done lock-free, we need to check if another
    // thread beat us in the race to insert the symbol.
    int index = hash_to_index(hashValues[i]);
309
    Symbol* test = lookup(index, names[i], lengths[i], hashValues[i]);
D
duke 已提交
310
    if (test != NULL) {
T
twisti 已提交
311
      // A race occurred and another thread introduced the symbol, this one
D
duke 已提交
312 313
      // will be dropped and collected. Use test instead.
      cp->symbol_at_put(cp_indices[i], test);
314 315
      assert(test->refcount() != 0, "lookup should have incremented the count");
      delete syms[i];
D
duke 已提交
316
    } else {
317 318 319
      Symbol* sym = syms[i];
      HashtableEntry<Symbol*>* entry = new_entry(hashValues[i], sym);
      sym->increment_refcount();  // increment refcount in external hashtable
D
duke 已提交
320 321 322 323 324 325 326 327 328 329 330
      add_entry(index, entry);
      cp->symbol_at_put(cp_indices[i], sym);
    }
  }

  return true;
}


void SymbolTable::verify() {
  for (int i = 0; i < the_table()->table_size(); ++i) {
331
    HashtableEntry<Symbol*>* p = the_table()->bucket(i);
D
duke 已提交
332
    for ( ; p != NULL; p = p->next()) {
333
      Symbol* s = (Symbol*)(p->literal());
D
duke 已提交
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
      guarantee(s != NULL, "symbol is NULL");
      unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length());
      guarantee(p->hash() == h, "broken hash in symbol table entry");
      guarantee(the_table()->hash_to_index(h) == i,
                "wrong index in symbol table");
    }
  }
}


//---------------------------------------------------------------------------
// Non-product code

#ifndef PRODUCT

void SymbolTable::print_histogram() {
  MutexLocker ml(SymbolTable_lock);
  const int results_length = 100;
  int results[results_length];
  int i,j;

  // initialize results to zero
  for (j = 0; j < results_length; j++) {
    results[j] = 0;
  }

  int total = 0;
  int max_symbols = 0;
  int out_of_range = 0;
363 364
  int memory_total = 0;
  int count = 0;
D
duke 已提交
365
  for (i = 0; i < the_table()->table_size(); i++) {
366
    HashtableEntry<Symbol*>* p = the_table()->bucket(i);
D
duke 已提交
367
    for ( ; p != NULL; p = p->next()) {
368 369 370
      memory_total += p->literal()->object_size();
      count++;
      int counter = p->literal()->utf8_length();
D
duke 已提交
371 372 373 374 375 376 377 378 379 380
      total += counter;
      if (counter < results_length) {
        results[counter]++;
      } else {
        out_of_range++;
      }
      max_symbols = MAX2(max_symbols, counter);
    }
  }
  tty->print_cr("Symbol Table:");
381 382 383 384 385 386 387 388 389 390 391
  tty->print_cr("Total number of symbols  %5d", count);
  tty->print_cr("Total size in memory     %5dK",
          (memory_total*HeapWordSize)/1024);
  tty->print_cr("Total counted            %5d", symbols_counted);
  tty->print_cr("Total removed            %5d", symbols_removed);
  if (symbols_counted > 0) {
    tty->print_cr("Percent removed          %3.2f",
          ((float)symbols_removed/(float)symbols_counted)* 100);
  }
  tty->print_cr("Reference counts         %5d", Symbol::_total_count);
  tty->print_cr("Histogram of symbol length:");
D
duke 已提交
392 393 394 395 396 397 398 399 400 401 402
  tty->print_cr("%8s %5d", "Total  ", total);
  tty->print_cr("%8s %5d", "Maximum", max_symbols);
  tty->print_cr("%8s %3.2f", "Average",
          ((float) total / (float) the_table()->table_size()));
  tty->print_cr("%s", "Histogram:");
  tty->print_cr(" %s %29s", "Length", "Number chains that length");
  for (i = 0; i < results_length; i++) {
    if (results[i] > 0) {
      tty->print_cr("%6d %10d", i, results[i]);
    }
  }
403 404 405 406 407 408 409 410 411 412 413 414 415
  if (Verbose) {
    int line_length = 70;
    tty->print_cr("%s %30s", " Length", "Number chains that length");
    for (i = 0; i < results_length; i++) {
      if (results[i] > 0) {
        tty->print("%4d", i);
        for (j = 0; (j < results[i]) && (j < line_length);  j++) {
          tty->print("%1s", "*");
        }
        if (j == line_length) {
          tty->print("%1s", "+");
        }
        tty->cr();
D
duke 已提交
416 417 418 419 420 421 422
      }
    }
  }
  tty->print_cr(" %s %d: %d\n", "Number chains longer than",
                    results_length, out_of_range);
}

423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
void SymbolTable::print() {
  for (int i = 0; i < the_table()->table_size(); ++i) {
    HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i);
    HashtableEntry<Symbol*>* entry = the_table()->bucket(i);
    if (entry != NULL) {
      while (entry != NULL) {
        tty->print(PTR_FORMAT " ", entry->literal());
        entry->literal()->print();
        tty->print(" %d", entry->literal()->refcount());
        p = entry->next_addr();
        entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p);
      }
      tty->cr();
    }
  }
}

D
duke 已提交
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
#endif // PRODUCT

// --------------------------------------------------------------------------

#ifdef ASSERT
class StableMemoryChecker : public StackObj {
  enum { _bufsize = wordSize*4 };

  address _region;
  jint    _size;
  u1      _save_buf[_bufsize];

  int sample(u1* save_buf) {
    if (_size <= _bufsize) {
      memcpy(save_buf, _region, _size);
      return _size;
    } else {
      // copy head and tail
      memcpy(&save_buf[0],          _region,                      _bufsize/2);
      memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2);
      return (_bufsize/2)*2;
    }
  }

 public:
  StableMemoryChecker(const void* region, jint size) {
    _region = (address) region;
    _size   = size;
    sample(_save_buf);
  }

  bool verify() {
    u1 check_buf[sizeof(_save_buf)];
    int check_size = sample(check_buf);
    return (0 == memcmp(_save_buf, check_buf, check_size));
  }

  void set_region(const void* region) { _region = (address) region; }
};
#endif


// --------------------------------------------------------------------------


// Compute the hash value for a java.lang.String object which would
// contain the characters passed in. This hash value is used for at
// least two purposes.
//
// (a) As the hash value used by the StringTable for bucket selection
//     and comparison (stored in the HashtableEntry structures).  This
//     is used in the String.intern() method.
//
// (b) As the hash value used by the String object itself, in
//     String.hashCode().  This value is normally calculate in Java code
//     in the String.hashCode method(), but is precomputed for String
//     objects in the shared archive file.
//
//     For this reason, THIS ALGORITHM MUST MATCH String.hashCode().

int StringTable::hash_string(jchar* s, int len) {
  unsigned h = 0;
  while (len-- > 0) {
    h = 31*h + (unsigned) *s;
    s++;
  }
  return h;
}


StringTable* StringTable::_the_table = NULL;

oop StringTable::lookup(int index, jchar* name,
                        int len, unsigned int hash) {
514
  for (HashtableEntry<oop>* l = bucket(index); l != NULL; l = l->next()) {
D
duke 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
    if (l->hash() == hash) {
      if (java_lang_String::equals(l->literal(), name, len)) {
        return l->literal();
      }
    }
  }
  return NULL;
}


oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
                           int len, unsigned int hashValue, TRAPS) {
  debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
  assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
         "proposed name of symbol must be stable");

  Handle string;
  // try to reuse the string if possible
  if (!string_or_null.is_null() && string_or_null()->is_perm()) {
    string = string_or_null;
  } else {
    string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
  }

  // Allocation must be done before grapping the SymbolTable_lock lock
  MutexLocker ml(StringTable_lock, THREAD);

  assert(java_lang_String::equals(string(), name, len),
         "string must be properly initialized");

  // Since look-up was done lock-free, we need to check if another
  // thread beat us in the race to insert the symbol.

  oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
  if (test != NULL) {
    // Entry already added
    return test;
  }

554
  HashtableEntry<oop>* entry = new_entry(hashValue, string());
D
duke 已提交
555 556 557 558 559
  add_entry(index, entry);
  return string();
}


560
oop StringTable::lookup(Symbol* symbol) {
D
duke 已提交
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
  ResourceMark rm;
  int length;
  jchar* chars = symbol->as_unicode(length);
  unsigned int hashValue = hash_string(chars, length);
  int index = the_table()->hash_to_index(hashValue);
  return the_table()->lookup(index, chars, length, hashValue);
}


oop StringTable::intern(Handle string_or_null, jchar* name,
                        int len, TRAPS) {
  unsigned int hashValue = hash_string(name, len);
  int index = the_table()->hash_to_index(hashValue);
  oop string = the_table()->lookup(index, name, len, hashValue);

  // Found
  if (string != NULL) return string;

  // Otherwise, add to symbol to table
  return the_table()->basic_add(index, string_or_null, name, len,
                                hashValue, CHECK_NULL);
}

584
oop StringTable::intern(Symbol* symbol, TRAPS) {
D
duke 已提交
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
  if (symbol == NULL) return NULL;
  ResourceMark rm(THREAD);
  int length;
  jchar* chars = symbol->as_unicode(length);
  Handle string;
  oop result = intern(string, chars, length, CHECK_NULL);
  return result;
}


oop StringTable::intern(oop string, TRAPS)
{
  if (string == NULL) return NULL;
  ResourceMark rm(THREAD);
  int length;
  Handle h_string (THREAD, string);
  jchar* chars = java_lang_String::as_unicode_string(string, length);
  oop result = intern(h_string, chars, length, CHECK_NULL);
  return result;
}


oop StringTable::intern(const char* utf8_string, TRAPS) {
  if (utf8_string == NULL) return NULL;
  ResourceMark rm(THREAD);
  int length = UTF8::unicode_length(utf8_string);
  jchar* chars = NEW_RESOURCE_ARRAY(jchar, length);
  UTF8::convert_to_unicode(utf8_string, chars, length);
  Handle string;
  oop result = intern(string, chars, length, CHECK_NULL);
  return result;
}

618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
void StringTable::unlink(BoolObjectClosure* is_alive) {
  // Readers of the table are unlocked, so we should only be removing
  // entries at a safepoint.
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  for (int i = 0; i < the_table()->table_size(); ++i) {
    for (HashtableEntry<oop>** p = the_table()->bucket_addr(i); *p != NULL; ) {
      HashtableEntry<oop>* entry = *p;
      if (entry->is_shared()) {
        break;
      }
      assert(entry->literal() != NULL, "just checking");
      if (is_alive->do_object_b(entry->literal())) {
        p = entry->next_addr();
      } else {
        *p = entry->next();
        the_table()->free_entry(entry);
      }
    }
  }
}

void StringTable::oops_do(OopClosure* f) {
  for (int i = 0; i < the_table()->table_size(); ++i) {
    HashtableEntry<oop>** p = the_table()->bucket_addr(i);
    HashtableEntry<oop>* entry = the_table()->bucket(i);
    while (entry != NULL) {
      f->do_oop((oop*)entry->literal_addr());

      // Did the closure remove the literal from the table?
      if (entry->literal() == NULL) {
        assert(!entry->is_shared(), "immutable hashtable entry?");
        *p = entry->next();
        the_table()->free_entry(entry);
      } else {
        p = entry->next_addr();
      }
      entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p);
    }
  }
}

D
duke 已提交
659 660
void StringTable::verify() {
  for (int i = 0; i < the_table()->table_size(); ++i) {
661
    HashtableEntry<oop>* p = the_table()->bucket(i);
D
duke 已提交
662 663 664 665 666 667 668 669 670 671 672 673 674 675
    for ( ; p != NULL; p = p->next()) {
      oop s = p->literal();
      guarantee(s != NULL, "interned string is NULL");
      guarantee(s->is_perm(), "interned string not in permspace");

      int length;
      jchar* chars = java_lang_String::as_unicode_string(s, length);
      unsigned int h = hash_string(chars, length);
      guarantee(p->hash() == h, "broken hash in string table entry");
      guarantee(the_table()->hash_to_index(h) == i,
                "wrong index in string table");
    }
  }
}