62 } |
62 } |
63 |
63 |
64 void SymbolTable::initialize_symbols(int arena_alloc_size) { |
64 void SymbolTable::initialize_symbols(int arena_alloc_size) { |
65 // Initialize the arena for global symbols, size passed in depends on CDS. |
65 // Initialize the arena for global symbols, size passed in depends on CDS. |
66 if (arena_alloc_size == 0) { |
66 if (arena_alloc_size == 0) { |
67 _arena = new Arena(); |
67 _arena = new (mtSymbol) Arena(); |
68 } else { |
68 } else { |
69 _arena = new Arena(arena_alloc_size); |
69 _arena = new (mtSymbol) Arena(arena_alloc_size); |
70 } |
70 } |
71 } |
71 } |
72 |
72 |
73 // Call function for all symbols in the symbol table. |
73 // Call function for all symbols in the symbol table. |
74 void SymbolTable::symbols_do(SymbolClosure *cl) { |
74 void SymbolTable::symbols_do(SymbolClosure *cl) { |
75 const int n = the_table()->table_size(); |
75 const int n = the_table()->table_size(); |
76 for (int i = 0; i < n; i++) { |
76 for (int i = 0; i < n; i++) { |
77 for (HashtableEntry<Symbol*>* p = the_table()->bucket(i); |
77 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); |
78 p != NULL; |
78 p != NULL; |
79 p = p->next()) { |
79 p = p->next()) { |
80 cl->do_symbol(p->literal_addr()); |
80 cl->do_symbol(p->literal_addr()); |
81 } |
81 } |
82 } |
82 } |
90 void SymbolTable::unlink() { |
90 void SymbolTable::unlink() { |
91 int removed = 0; |
91 int removed = 0; |
92 int total = 0; |
92 int total = 0; |
93 size_t memory_total = 0; |
93 size_t memory_total = 0; |
94 for (int i = 0; i < the_table()->table_size(); ++i) { |
94 for (int i = 0; i < the_table()->table_size(); ++i) { |
95 HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); |
95 HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i); |
96 HashtableEntry<Symbol*>* entry = the_table()->bucket(i); |
96 HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i); |
97 while (entry != NULL) { |
97 while (entry != NULL) { |
98 // Shared entries are normally at the end of the bucket and if we run into |
98 // Shared entries are normally at the end of the bucket and if we run into |
99 // a shared entry, then there is nothing more to remove. However, if we |
99 // a shared entry, then there is nothing more to remove. However, if we |
100 // have rehashed the table, then the shared entries are no longer at the |
100 // have rehashed the table, then the shared entries are no longer at the |
101 // end of the bucket. |
101 // end of the bucket. |
115 the_table()->free_entry(entry); |
115 the_table()->free_entry(entry); |
116 } else { |
116 } else { |
117 p = entry->next_addr(); |
117 p = entry->next_addr(); |
118 } |
118 } |
119 // get next entry |
119 // get next entry |
120 entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p); |
120 entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p); |
121 } |
121 } |
122 } |
122 } |
123 symbols_removed += removed; |
123 symbols_removed += removed; |
124 symbols_counted += total; |
124 symbols_counted += total; |
125 // Exclude printing for normal PrintGCDetails because people parse |
125 // Exclude printing for normal PrintGCDetails because people parse |
162 // Lookup a symbol in a bucket. |
162 // Lookup a symbol in a bucket. |
163 |
163 |
164 Symbol* SymbolTable::lookup(int index, const char* name, |
164 Symbol* SymbolTable::lookup(int index, const char* name, |
165 int len, unsigned int hash) { |
165 int len, unsigned int hash) { |
166 int count = 0; |
166 int count = 0; |
167 for (HashtableEntry<Symbol*>* e = bucket(index); e != NULL; e = e->next()) { |
167 for (HashtableEntry<Symbol*, mtSymbol>* e = bucket(index); e != NULL; e = e->next()) { |
168 count++; // count all entries in this bucket, not just ones with same hash |
168 count++; // count all entries in this bucket, not just ones with same hash |
169 if (e->hash() == hash) { |
169 if (e->hash() == hash) { |
170 Symbol* sym = e->literal(); |
170 Symbol* sym = e->literal(); |
171 if (sym->equals(name, len)) { |
171 if (sym->equals(name, len)) { |
172 // something is referencing this symbol now. |
172 // something is referencing this symbol now. |
266 // Do not increment the reference count to keep this alive |
266 // Do not increment the reference count to keep this alive |
267 Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){ |
267 Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){ |
268 unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length()); |
268 unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length()); |
269 int index = the_table()->hash_to_index(hash); |
269 int index = the_table()->hash_to_index(hash); |
270 |
270 |
271 for (HashtableEntry<Symbol*>* e = the_table()->bucket(index); e != NULL; e = e->next()) { |
271 for (HashtableEntry<Symbol*, mtSymbol>* e = the_table()->bucket(index); e != NULL; e = e->next()) { |
272 if (e->hash() == hash) { |
272 if (e->hash() == hash) { |
273 Symbol* literal_sym = e->literal(); |
273 Symbol* literal_sym = e->literal(); |
274 if (sym == literal_sym) { |
274 if (sym == literal_sym) { |
275 return e->literal_addr(); |
275 return e->literal_addr(); |
276 } |
276 } |
385 |
385 |
386 // Create a new symbol. |
386 // Create a new symbol. |
387 Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL); |
387 Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL); |
388 assert(sym->equals((char*)name, len), "symbol must be properly initialized"); |
388 assert(sym->equals((char*)name, len), "symbol must be properly initialized"); |
389 |
389 |
390 HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym); |
390 HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym); |
391 add_entry(index, entry); |
391 add_entry(index, entry); |
392 return sym; |
392 return sym; |
393 } |
393 } |
394 |
394 |
395 // This version of basic_add adds symbols in batch from the constant pool |
395 // This version of basic_add adds symbols in batch from the constant pool |
433 // Create a new symbol. The null class loader is never unloaded so these |
433 // Create a new symbol. The null class loader is never unloaded so these |
434 // are allocated specially in a permanent arena. |
434 // are allocated specially in a permanent arena. |
435 bool c_heap = class_loader() != NULL; |
435 bool c_heap = class_loader() != NULL; |
436 Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false)); |
436 Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false)); |
437 assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized"); // why wouldn't it be??? |
437 assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized"); // why wouldn't it be??? |
438 HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym); |
438 HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym); |
439 add_entry(index, entry); |
439 add_entry(index, entry); |
440 cp->symbol_at_put(cp_indices[i], sym); |
440 cp->symbol_at_put(cp_indices[i], sym); |
441 } |
441 } |
442 } |
442 } |
443 return true; |
443 return true; |
444 } |
444 } |
445 |
445 |
446 |
446 |
447 void SymbolTable::verify() { |
447 void SymbolTable::verify() { |
448 for (int i = 0; i < the_table()->table_size(); ++i) { |
448 for (int i = 0; i < the_table()->table_size(); ++i) { |
449 HashtableEntry<Symbol*>* p = the_table()->bucket(i); |
449 HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); |
450 for ( ; p != NULL; p = p->next()) { |
450 for ( ; p != NULL; p = p->next()) { |
451 Symbol* s = (Symbol*)(p->literal()); |
451 Symbol* s = (Symbol*)(p->literal()); |
452 guarantee(s != NULL, "symbol is NULL"); |
452 guarantee(s != NULL, "symbol is NULL"); |
453 unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length()); |
453 unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length()); |
454 guarantee(p->hash() == h, "broken hash in symbol table entry"); |
454 guarantee(p->hash() == h, "broken hash in symbol table entry"); |
460 |
460 |
461 void SymbolTable::dump(outputStream* st) { |
461 void SymbolTable::dump(outputStream* st) { |
462 NumberSeq summary; |
462 NumberSeq summary; |
463 for (int i = 0; i < the_table()->table_size(); ++i) { |
463 for (int i = 0; i < the_table()->table_size(); ++i) { |
464 int count = 0; |
464 int count = 0; |
465 for (HashtableEntry<Symbol*>* e = the_table()->bucket(i); |
465 for (HashtableEntry<Symbol*, mtSymbol>* e = the_table()->bucket(i); |
466 e != NULL; e = e->next()) { |
466 e != NULL; e = e->next()) { |
467 count++; |
467 count++; |
468 } |
468 } |
469 summary.add((double)count); |
469 summary.add((double)count); |
470 } |
470 } |
497 int max_symbols = 0; |
497 int max_symbols = 0; |
498 int out_of_range = 0; |
498 int out_of_range = 0; |
499 int memory_total = 0; |
499 int memory_total = 0; |
500 int count = 0; |
500 int count = 0; |
501 for (i = 0; i < the_table()->table_size(); i++) { |
501 for (i = 0; i < the_table()->table_size(); i++) { |
502 HashtableEntry<Symbol*>* p = the_table()->bucket(i); |
502 HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); |
503 for ( ; p != NULL; p = p->next()) { |
503 for ( ; p != NULL; p = p->next()) { |
504 memory_total += p->literal()->object_size(); |
504 memory_total += p->literal()->object_size(); |
505 count++; |
505 count++; |
506 int counter = p->literal()->utf8_length(); |
506 int counter = p->literal()->utf8_length(); |
507 total += counter; |
507 total += counter; |
558 results_length, out_of_range); |
558 results_length, out_of_range); |
559 } |
559 } |
560 |
560 |
561 void SymbolTable::print() { |
561 void SymbolTable::print() { |
562 for (int i = 0; i < the_table()->table_size(); ++i) { |
562 for (int i = 0; i < the_table()->table_size(); ++i) { |
563 HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); |
563 HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i); |
564 HashtableEntry<Symbol*>* entry = the_table()->bucket(i); |
564 HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i); |
565 if (entry != NULL) { |
565 if (entry != NULL) { |
566 while (entry != NULL) { |
566 while (entry != NULL) { |
567 tty->print(PTR_FORMAT " ", entry->literal()); |
567 tty->print(PTR_FORMAT " ", entry->literal()); |
568 entry->literal()->print(); |
568 entry->literal()->print(); |
569 tty->print(" %d", entry->literal()->refcount()); |
569 tty->print(" %d", entry->literal()->refcount()); |
570 p = entry->next_addr(); |
570 p = entry->next_addr(); |
571 entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p); |
571 entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p); |
572 } |
572 } |
573 tty->cr(); |
573 tty->cr(); |
574 } |
574 } |
575 } |
575 } |
576 } |
576 } |
629 } |
629 } |
630 |
630 |
631 oop StringTable::lookup(int index, jchar* name, |
631 oop StringTable::lookup(int index, jchar* name, |
632 int len, unsigned int hash) { |
632 int len, unsigned int hash) { |
633 int count = 0; |
633 int count = 0; |
634 for (HashtableEntry<oop>* l = bucket(index); l != NULL; l = l->next()) { |
634 for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) { |
635 count++; |
635 count++; |
636 if (l->hash() == hash) { |
636 if (l->hash() == hash) { |
637 if (java_lang_String::equals(l->literal(), name, len)) { |
637 if (java_lang_String::equals(l->literal(), name, len)) { |
638 return l->literal(); |
638 return l->literal(); |
639 } |
639 } |
640 } |
640 } |
641 } |
641 } |
642 // If the bucket size is too deep check if this hash code is insufficient. |
642 // If the bucket size is too deep check if this hash code is insufficient. |
643 if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { |
643 if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) { |
644 _needs_rehashing = check_rehash_table(count); |
644 _needs_rehashing = check_rehash_table(count); |
645 } |
645 } |
646 return NULL; |
646 return NULL; |
647 } |
647 } |
648 |
648 |
759 void StringTable::unlink(BoolObjectClosure* is_alive) { |
759 void StringTable::unlink(BoolObjectClosure* is_alive) { |
760 // Readers of the table are unlocked, so we should only be removing |
760 // Readers of the table are unlocked, so we should only be removing |
761 // entries at a safepoint. |
761 // entries at a safepoint. |
762 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
762 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
763 for (int i = 0; i < the_table()->table_size(); ++i) { |
763 for (int i = 0; i < the_table()->table_size(); ++i) { |
764 HashtableEntry<oop>** p = the_table()->bucket_addr(i); |
764 HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); |
765 HashtableEntry<oop>* entry = the_table()->bucket(i); |
765 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); |
766 while (entry != NULL) { |
766 while (entry != NULL) { |
767 // Shared entries are normally at the end of the bucket and if we run into |
767 // Shared entries are normally at the end of the bucket and if we run into |
768 // a shared entry, then there is nothing more to remove. However, if we |
768 // a shared entry, then there is nothing more to remove. However, if we |
769 // have rehashed the table, then the shared entries are no longer at the |
769 // have rehashed the table, then the shared entries are no longer at the |
770 // end of the bucket. |
770 // end of the bucket. |
776 p = entry->next_addr(); |
776 p = entry->next_addr(); |
777 } else { |
777 } else { |
778 *p = entry->next(); |
778 *p = entry->next(); |
779 the_table()->free_entry(entry); |
779 the_table()->free_entry(entry); |
780 } |
780 } |
781 entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p); |
781 entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p); |
782 } |
782 } |
783 } |
783 } |
784 } |
784 } |
785 |
785 |
786 void StringTable::oops_do(OopClosure* f) { |
786 void StringTable::oops_do(OopClosure* f) { |
787 for (int i = 0; i < the_table()->table_size(); ++i) { |
787 for (int i = 0; i < the_table()->table_size(); ++i) { |
788 HashtableEntry<oop>** p = the_table()->bucket_addr(i); |
788 HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); |
789 HashtableEntry<oop>* entry = the_table()->bucket(i); |
789 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); |
790 while (entry != NULL) { |
790 while (entry != NULL) { |
791 f->do_oop((oop*)entry->literal_addr()); |
791 f->do_oop((oop*)entry->literal_addr()); |
792 |
792 |
793 // Did the closure remove the literal from the table? |
793 // Did the closure remove the literal from the table? |
794 if (entry->literal() == NULL) { |
794 if (entry->literal() == NULL) { |
796 *p = entry->next(); |
796 *p = entry->next(); |
797 the_table()->free_entry(entry); |
797 the_table()->free_entry(entry); |
798 } else { |
798 } else { |
799 p = entry->next_addr(); |
799 p = entry->next_addr(); |
800 } |
800 } |
801 entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p); |
801 entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p); |
802 } |
802 } |
803 } |
803 } |
804 } |
804 } |
805 |
805 |
806 void StringTable::verify() { |
806 void StringTable::verify() { |
807 for (int i = 0; i < the_table()->table_size(); ++i) { |
807 for (int i = 0; i < the_table()->table_size(); ++i) { |
808 HashtableEntry<oop>* p = the_table()->bucket(i); |
808 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); |
809 for ( ; p != NULL; p = p->next()) { |
809 for ( ; p != NULL; p = p->next()) { |
810 oop s = p->literal(); |
810 oop s = p->literal(); |
811 guarantee(s != NULL, "interned string is NULL"); |
811 guarantee(s != NULL, "interned string is NULL"); |
812 guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace"); |
812 guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace"); |
813 unsigned int h = java_lang_String::hash_string(s); |
813 unsigned int h = java_lang_String::hash_string(s); |
819 } |
819 } |
820 |
820 |
821 void StringTable::dump(outputStream* st) { |
821 void StringTable::dump(outputStream* st) { |
822 NumberSeq summary; |
822 NumberSeq summary; |
823 for (int i = 0; i < the_table()->table_size(); ++i) { |
823 for (int i = 0; i < the_table()->table_size(); ++i) { |
824 HashtableEntry<oop>* p = the_table()->bucket(i); |
824 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); |
825 int count = 0; |
825 int count = 0; |
826 for ( ; p != NULL; p = p->next()) { |
826 for ( ; p != NULL; p = p->next()) { |
827 count++; |
827 count++; |
828 } |
828 } |
829 summary.add((double)count); |
829 summary.add((double)count); |