1 /* 2 * Copyright (c) 1997, 2013, 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 */ 24 25 #ifndef SHARE_VM_CLASSFILE_STRINGTABLE_HPP 26 #define SHARE_VM_CLASSFILE_STRINGTABLE_HPP 27 28 #include "memory/allocation.inline.hpp" 29 #include "utilities/hashtable.hpp" 30 31 class StringTable : public Hashtable<oop, mtSymbol> { 32 friend class VMStructs; 33 friend class Symbol; 34 35 private: 36 // The string table 37 static StringTable* _the_table; 38 39 // Set if one bucket is out of balance due to hash algorithm deficiency 40 static bool _needs_rehashing; 41 42 // Claimed high water mark for parallel chunked scanning 43 static volatile int _parallel_claimed_idx; 44 45 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 46 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 47 unsigned int hashValue, TRAPS); 48 49 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); 50 51 // Apply the give oop closure to the entries to the buckets 52 // in the range [start_idx, end_idx). 53 static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); 54 // Unlink or apply the give oop closure to the entries to the buckets 55 // in the range [start_idx, end_idx). 56 static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); 57 58 StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, 59 sizeof (HashtableEntry<oop, mtSymbol>)) {} 60 61 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) 62 : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t, 63 number_of_entries) {} 64 public: 65 // The string table 66 static StringTable* the_table() { return _the_table; } 67 68 // Size of one bucket in the string table. Used when checking for rollover. 69 static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); } 70 71 static void create_table() { 72 assert(_the_table == NULL, "One string table allowed."); 73 _the_table = new StringTable(); 74 } 75 76 // GC support 77 // Delete pointers to otherwise-unreachable objects. 78 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { 79 int processed = 0; 80 int removed = 0; 81 unlink_or_oops_do(cl, f, &processed, &removed); 82 } 83 static void unlink(BoolObjectClosure* cl) { 84 int processed = 0; 85 int removed = 0; 86 unlink_or_oops_do(cl, NULL, &processed, &removed); 87 } 88 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); 89 static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { 90 unlink_or_oops_do(cl, NULL, processed, removed); 91 } 92 // Serially invoke "f->do_oop" on the locations of all oops in the table. 93 static void oops_do(OopClosure* f); 94 95 // Possibly parallel versions of the above 96 static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); 97 static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { 98 possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); 99 } 100 static void possibly_parallel_oops_do(OopClosure* f); 101 102 // Hashing algorithm, used as the hash value used by the 103 // StringTable for bucket selection and comparison (stored in the 104 // HashtableEntry structures). This is used in the String.intern() method. 105 static unsigned int hash_string(const jchar* s, int len); 106 107 // Internal test. 108 static void test_alt_hash() PRODUCT_RETURN; 109 110 // Probing 111 static oop lookup(Symbol* symbol); 112 static oop lookup(jchar* chars, int length); 113 114 // Interning 115 static oop intern(Symbol* symbol, TRAPS); 116 static oop intern(oop string, TRAPS); 117 static oop intern(const char *utf8_string, TRAPS); 118 119 // Debugging 120 static void verify(); 121 static void dump(outputStream* st); 122 123 enum VerifyMesgModes { 124 _verify_quietly = 0, 125 _verify_with_mesgs = 1 126 }; 127 128 enum VerifyRetTypes { 129 _verify_pass = 0, 130 _verify_fail_continue = 1, 131 _verify_fail_done = 2 132 }; 133 134 static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, 135 HashtableEntry<oop, mtSymbol>* e_ptr1, 136 int bkt2, int e_cnt2, 137 HashtableEntry<oop, mtSymbol>* e_ptr2); 138 static VerifyRetTypes verify_entry(int bkt, int e_cnt, 139 HashtableEntry<oop, mtSymbol>* e_ptr, 140 VerifyMesgModes mesg_mode); 141 static int verify_and_compare_entries(); 142 143 // Sharing 144 static void copy_buckets(char** top, char*end) { 145 the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end); 146 } 147 static void copy_table(char** top, char*end) { 148 the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end); 149 } 150 static void reverse() { 151 the_table()->Hashtable<oop, mtSymbol>::reverse(); 152 } 153 154 // Rehash the symbol table if it gets out of balance 155 static void rehash_table(); 156 static bool needs_rehashing() { return _needs_rehashing; } 157 158 // Parallel chunked scanning 159 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } 160 static int parallel_claimed_index() { return _parallel_claimed_idx; } 161 }; 162 #endif // SHARE_VM_CLASSFILE_STRINGTABLE_HPP