593 _size = size;
594 sample(_save_buf);
595 }
596
597 bool verify() {
598 u1 check_buf[sizeof(_save_buf)];
599 int check_size = sample(check_buf);
600 return (0 == memcmp(_save_buf, check_buf, check_size));
601 }
602
603 void set_region(const void* region) { _region = (address) region; }
604 };
605 #endif
606
607
608 // --------------------------------------------------------------------------
609 StringTable* StringTable::_the_table = NULL;
610
611 bool StringTable::_needs_rehashing = false;
612
613 // Pick hashing algorithm
614 unsigned int StringTable::hash_string(const jchar* s, int len) {
615 return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
616 java_lang_String::to_hash(s, len);
617 }
618
619 oop StringTable::lookup(int index, jchar* name,
620 int len, unsigned int hash) {
621 int count = 0;
622 for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
623 count++;
624 if (l->hash() == hash) {
625 if (java_lang_String::equals(l->literal(), name, len)) {
626 return l->literal();
627 }
628 }
629 }
630 // If the bucket size is too deep check if this hash code is insufficient.
631 if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
632 _needs_rehashing = check_rehash_table(count);
754 while (entry != NULL) {
755 // Shared entries are normally at the end of the bucket and if we run into
756 // a shared entry, then there is nothing more to remove. However, if we
757 // have rehashed the table, then the shared entries are no longer at the
758 // end of the bucket.
759 if (entry->is_shared() && !use_alternate_hashcode()) {
760 break;
761 }
762 assert(entry->literal() != NULL, "just checking");
763 if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
764 p = entry->next_addr();
765 } else {
766 *p = entry->next();
767 the_table()->free_entry(entry);
768 }
769 entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
770 }
771 }
772 }
773
774 void StringTable::oops_do(OopClosure* f) {
775 for (int i = 0; i < the_table()->table_size(); ++i) {
776 HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
777 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
778 while (entry != NULL) {
779 f->do_oop((oop*)entry->literal_addr());
780
781 // Did the closure remove the literal from the table?
782 if (entry->literal() == NULL) {
783 assert(!entry->is_shared(), "immutable hashtable entry?");
784 *p = entry->next();
785 the_table()->free_entry(entry);
786 } else {
787 p = entry->next_addr();
788 }
789 entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
790 }
791 }
792 }
793
794 void StringTable::verify() {
795 for (int i = 0; i < the_table()->table_size(); ++i) {
796 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
797 for ( ; p != NULL; p = p->next()) {
798 oop s = p->literal();
799 guarantee(s != NULL, "interned string is NULL");
800 guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
801 unsigned int h = java_lang_String::hash_string(s);
802 guarantee(p->hash() == h, "broken hash in string table entry");
803 guarantee(the_table()->hash_to_index(h) == i,
804 "wrong index in string table");
805 }
806 }
807 }
808
809 void StringTable::dump(outputStream* st) {
810 NumberSeq summary;
811 for (int i = 0; i < the_table()->table_size(); ++i) {
812 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
813 int count = 0;
|
593 _size = size;
594 sample(_save_buf);
595 }
596
597 bool verify() {
598 u1 check_buf[sizeof(_save_buf)];
599 int check_size = sample(check_buf);
600 return (0 == memcmp(_save_buf, check_buf, check_size));
601 }
602
603 void set_region(const void* region) { _region = (address) region; }
604 };
605 #endif
606
607
608 // --------------------------------------------------------------------------
609 StringTable* StringTable::_the_table = NULL;
610
611 bool StringTable::_needs_rehashing = false;
612
613 volatile int StringTable::_parallel_claimed_idx = 0;
614
615 // Pick hashing algorithm
616 unsigned int StringTable::hash_string(const jchar* s, int len) {
617 return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
618 java_lang_String::to_hash(s, len);
619 }
620
621 oop StringTable::lookup(int index, jchar* name,
622 int len, unsigned int hash) {
623 int count = 0;
624 for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
625 count++;
626 if (l->hash() == hash) {
627 if (java_lang_String::equals(l->literal(), name, len)) {
628 return l->literal();
629 }
630 }
631 }
632 // If the bucket size is too deep check if this hash code is insufficient.
633 if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
634 _needs_rehashing = check_rehash_table(count);
756 while (entry != NULL) {
757 // Shared entries are normally at the end of the bucket and if we run into
758 // a shared entry, then there is nothing more to remove. However, if we
759 // have rehashed the table, then the shared entries are no longer at the
760 // end of the bucket.
761 if (entry->is_shared() && !use_alternate_hashcode()) {
762 break;
763 }
764 assert(entry->literal() != NULL, "just checking");
765 if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
766 p = entry->next_addr();
767 } else {
768 *p = entry->next();
769 the_table()->free_entry(entry);
770 }
771 entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
772 }
773 }
774 }
775
776 void StringTable::buckets_do(OopClosure* f, int start_idx, int end_idx) {
777 const int limit = the_table()->table_size();
778
779 assert(0 <= start_idx && start_idx <= limit,
780 err_msg("start_idx (" INT32_FORMAT ") oob?", start_idx));
781 assert(0 <= end_idx && end_idx <= limit,
782 err_msg("end_idx (" INT32_FORMAT ") oob?", end_idx));
783 assert(start_idx <= end_idx,
784 err_msg("Ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT,
785 start_idx, end_idx));
786
787 for (int i = start_idx; i < end_idx; i += 1) {
788 HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
789 HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
790 while (entry != NULL) {
791 f->do_oop((oop*)entry->literal_addr());
792
793 // Did the closure remove the literal from the table?
794 if (entry->literal() == NULL) {
795 assert(!entry->is_shared(), "immutable hashtable entry?");
796 *p = entry->next();
797 the_table()->free_entry(entry);
798 } else {
799 p = entry->next_addr();
800 }
801 entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
802 }
803 }
804 }
805
806 void StringTable::oops_do(OopClosure* f) {
807 buckets_do(f, 0, the_table()->table_size());
808 }
809
810 void StringTable::possibly_parallel_oops_do(OopClosure* f) {
811 const int ClaimChunkSize = 32;
812 const int limit = the_table()->table_size();
813
814 for (;;) {
815 // Grab next set of buckets to scan
816 int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
817 if (start_idx >= limit) {
818 // End of table
819 break;
820 }
821
822 int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
823 buckets_do(f, start_idx, end_idx);
824 }
825 }
826
827 void StringTable::verify() {
828 for (int i = 0; i < the_table()->table_size(); ++i) {
829 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
830 for ( ; p != NULL; p = p->next()) {
831 oop s = p->literal();
832 guarantee(s != NULL, "interned string is NULL");
833 guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
834 unsigned int h = java_lang_String::hash_string(s);
835 guarantee(p->hash() == h, "broken hash in string table entry");
836 guarantee(the_table()->hash_to_index(h) == i,
837 "wrong index in string table");
838 }
839 }
840 }
841
842 void StringTable::dump(outputStream* st) {
843 NumberSeq summary;
844 for (int i = 0; i < the_table()->table_size(); ++i) {
845 HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
846 int count = 0;
|