94 CompactHashtable<oop, char> StringTable::_shared_table;
95
96 // Pick hashing algorithm
97 template<typename T>
98 unsigned int StringTable::hash_string(const T* s, int len) {
99 return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
100 java_lang_String::hash_code(s, len);
101 }
102
103 // Explicit instantiation for all supported types.
104 template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len);
105 template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len);
106
107 oop StringTable::lookup_shared(jchar* name, int len) {
108 // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
109 // use the hash value from StringTable::hash_string() as it might use alternate hashcode.
110 return _shared_table.lookup((const char*)name,
111 java_lang_String::hash_code(name, len), len);
112 }
113
114 oop StringTable::lookup_in_main_table(int index, jchar* name,
115 int len, unsigned int hash) {
116 int count = 0;
117 for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
118 count++;
119 if (l->hash() == hash) {
120 if (java_lang_String::equals(l->literal(), name, len)) {
121 return l->literal();
122 }
123 }
124 }
125 // If the bucket size is too deep check if this hash code is insufficient.
126 if (count >= rehash_count && !needs_rehashing()) {
127 _needs_rehashing = check_rehash_table(count);
128 }
129 return NULL;
130 }
131
132
133 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
134 int len, unsigned int hashValue_arg, TRAPS) {
135
136 assert(java_lang_String::equals(string(), name, len),
137 "string must be properly initialized");
138 // Cannot hit a safepoint in this function because the "this" pointer can move.
139 NoSafepointVerifier nsv;
140
141 // Check if the symbol table has been rehashed, if so, need to recalculate
156 // No need to lookup the shared table from here since the caller (intern()) already did
157 oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
158 if (test != NULL) {
159 // Entry already added
160 return test;
161 }
162
163 HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
164 add_entry(index, entry);
165 return string();
166 }
167
168
169 oop StringTable::lookup(Symbol* symbol) {
170 ResourceMark rm;
171 int length;
172 jchar* chars = symbol->as_unicode(length);
173 return lookup(chars, length);
174 }
175
176 // Tell the GC that this string was looked up in the StringTable.
177 static void ensure_string_alive(oop string) {
178 // A lookup in the StringTable could return an object that was previously
179 // considered dead. The SATB part of G1 needs to get notified about this
180 // potential resurrection, otherwise the marking might not find the object.
181 #if INCLUDE_ALL_GCS
182 if (UseG1GC && string != NULL) {
183 G1SATBCardTableModRefBS::enqueue(string);
184 }
185 #endif
186 }
187
188 oop StringTable::lookup(jchar* name, int len) {
189 oop string = lookup_shared(name, len);
190 if (string != NULL) {
191 return string;
192 }
193
194 unsigned int hash = hash_string(name, len);
195 int index = the_table()->hash_to_index(hash);
196 string = the_table()->lookup_in_main_table(index, name, len, hash);
197
198 ensure_string_alive(string);
199
200 return string;
201 }
202
203
204 oop StringTable::intern(Handle string_or_null, jchar* name,
205 int len, TRAPS) {
206 oop found_string = lookup_shared(name, len);
207 if (found_string != NULL) {
208 return found_string;
209 }
210
211 unsigned int hashValue = hash_string(name, len);
212 int index = the_table()->hash_to_index(hashValue);
213 found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
214
215 // Found
216 if (found_string != NULL) {
217 ensure_string_alive(found_string);
218 return found_string;
219 }
220
221 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
222 assert(!Universe::heap()->is_in_reserved(name),
223 "proposed name of symbol must be stable");
224
225 Handle string;
226 // try to reuse the string if possible
227 if (!string_or_null.is_null()) {
228 string = string_or_null;
229 } else {
230 string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
231 }
232
233 #if INCLUDE_ALL_GCS
234 if (G1StringDedup::is_enabled()) {
235 // Deduplicate the string before it is interned. Note that we should never
236 // deduplicate a string after it has been interned. Doing so will counteract
237 // compiler optimizations done on e.g. interned string literals.
238 G1StringDedup::deduplicate(string());
239 }
240 #endif
241
242 // Grab the StringTable_lock before getting the_table() because it could
243 // change at safepoint.
244 oop added_or_found;
245 {
246 MutexLocker ml(StringTable_lock, THREAD);
247 // Otherwise, add to symbol to table
248 added_or_found = the_table()->basic_add(index, string, name, len,
249 hashValue, CHECK_NULL);
250 }
251
252 ensure_string_alive(added_or_found);
253
254 return added_or_found;
255 }
256
257 oop StringTable::intern(Symbol* symbol, TRAPS) {
258 if (symbol == NULL) return NULL;
259 ResourceMark rm(THREAD);
260 int length;
261 jchar* chars = symbol->as_unicode(length);
262 Handle string;
263 oop result = intern(string, chars, length, CHECK_NULL);
264 return result;
265 }
266
267
268 oop StringTable::intern(oop string, TRAPS)
269 {
270 if (string == NULL) return NULL;
271 ResourceMark rm(THREAD);
272 int length;
|
94 CompactHashtable<oop, char> StringTable::_shared_table;
95
96 // Pick hashing algorithm
97 template<typename T>
98 unsigned int StringTable::hash_string(const T* s, int len) {
99 return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
100 java_lang_String::hash_code(s, len);
101 }
102
103 // Explicit instantiation for all supported types.
104 template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len);
105 template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len);
106
107 oop StringTable::lookup_shared(jchar* name, int len) {
108 // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
109 // use the hash value from StringTable::hash_string() as it might use alternate hashcode.
110 return _shared_table.lookup((const char*)name,
111 java_lang_String::hash_code(name, len), len);
112 }
113
114 // Tell the GC that this string was looked up in the StringTable.
115 static void ensure_string_alive(oop string) {
116 // A lookup in the StringTable could return an object that was previously
117 // considered dead. The SATB part of G1 needs to get notified about this
118 // potential resurrection, otherwise the marking might not find the object.
119 #if INCLUDE_ALL_GCS
120 assert(string != NULL, "should only be called when string found in table");
121 if (UseG1GC) {
122 G1SATBCardTableModRefBS::enqueue(string);
123 }
124 #endif
125 }
126
127 oop StringTable::lookup_in_main_table(int index, jchar* name,
128 int len, unsigned int hash) {
129 int count = 0;
130 for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
131 count++;
132 if (l->hash() == hash) {
133 if (java_lang_String::equals(l->literal(), name, len)) {
134 oop result = l->literal();
135 ensure_string_alive(result);
136 return result;
137 }
138 }
139 }
140 // If the bucket size is too deep check if this hash code is insufficient.
141 if (count >= rehash_count && !needs_rehashing()) {
142 _needs_rehashing = check_rehash_table(count);
143 }
144 return NULL;
145 }
146
147
148 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
149 int len, unsigned int hashValue_arg, TRAPS) {
150
151 assert(java_lang_String::equals(string(), name, len),
152 "string must be properly initialized");
153 // Cannot hit a safepoint in this function because the "this" pointer can move.
154 NoSafepointVerifier nsv;
155
156 // Check if the symbol table has been rehashed, if so, need to recalculate
171 // No need to lookup the shared table from here since the caller (intern()) already did
172 oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
173 if (test != NULL) {
174 // Entry already added
175 return test;
176 }
177
178 HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
179 add_entry(index, entry);
180 return string();
181 }
182
183
184 oop StringTable::lookup(Symbol* symbol) {
185 ResourceMark rm;
186 int length;
187 jchar* chars = symbol->as_unicode(length);
188 return lookup(chars, length);
189 }
190
191 oop StringTable::lookup(jchar* name, int len) {
192 oop string = lookup_shared(name, len);
193 if (string != NULL) {
194 return string;
195 }
196
197 unsigned int hash = hash_string(name, len);
198 int index = the_table()->hash_to_index(hash);
199 string = the_table()->lookup_in_main_table(index, name, len, hash);
200 return string;
201 }
202
203
204 oop StringTable::intern(Handle string_or_null, jchar* name,
205 int len, TRAPS) {
206 oop found_string = lookup_shared(name, len);
207 if (found_string != NULL) {
208 return found_string;
209 }
210
211 unsigned int hashValue = hash_string(name, len);
212 int index = the_table()->hash_to_index(hashValue);
213 found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
214
215 // Found
216 if (found_string != NULL) {
217 return found_string;
218 }
219
220 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
221 assert(!Universe::heap()->is_in_reserved(name),
222 "proposed name of symbol must be stable");
223
224 Handle string;
225 // try to reuse the string if possible
226 if (!string_or_null.is_null()) {
227 string = string_or_null;
228 } else {
229 string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
230 }
231
232 #if INCLUDE_ALL_GCS
233 if (G1StringDedup::is_enabled()) {
234 // Deduplicate the string before it is interned. Note that we should never
235 // deduplicate a string after it has been interned. Doing so will counteract
236 // compiler optimizations done on e.g. interned string literals.
237 G1StringDedup::deduplicate(string());
238 }
239 #endif
240
241 // Grab the StringTable_lock before getting the_table() because it could
242 // change at safepoint.
243 oop added_or_found;
244 {
245 MutexLocker ml(StringTable_lock, THREAD);
246 // Otherwise, add to symbol to table
247 added_or_found = the_table()->basic_add(index, string, name, len,
248 hashValue, CHECK_NULL);
249 }
250
251 return added_or_found;
252 }
253
254 oop StringTable::intern(Symbol* symbol, TRAPS) {
255 if (symbol == NULL) return NULL;
256 ResourceMark rm(THREAD);
257 int length;
258 jchar* chars = symbol->as_unicode(length);
259 Handle string;
260 oop result = intern(string, chars, length, CHECK_NULL);
261 return result;
262 }
263
264
265 oop StringTable::intern(oop string, TRAPS)
266 {
267 if (string == NULL) return NULL;
268 ResourceMark rm(THREAD);
269 int length;
|