1 /*
2 * Copyright (c) 1997, 2016, 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 *
79 int check_size = sample(check_buf);
80 return (0 == memcmp(_save_buf, check_buf, check_size));
81 }
82
83 void set_region(const void* region) { _region = (address) region; }
84 };
85 #endif
86
87
88 // --------------------------------------------------------------------------
89 StringTable* StringTable::_the_table = NULL;
90 bool StringTable::_ignore_shared_strings = false;
91 bool StringTable::_needs_rehashing = false;
92
93 volatile int StringTable::_parallel_claimed_idx = 0;
94
95 CompactHashtable<oop, char> StringTable::_shared_table;
96
97 // Pick hashing algorithm
98 unsigned int StringTable::hash_string(const jchar* 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 unsigned int StringTable::hash_string(oop string) {
104 EXCEPTION_MARK;
105 if (string == NULL) {
106 return hash_string((jchar*)NULL, 0);
107 }
108 ResourceMark rm(THREAD);
109 // All String oops are hashed as unicode
110 int length;
111 jchar* chars = java_lang_String::as_unicode_string(string, length, THREAD);
112 if (chars != NULL) {
113 return hash_string(chars, length);
114 } else {
115 vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
116 return 0;
117 }
118 }
119
120 oop StringTable::lookup_shared(jchar* name, int len) {
121 // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
122 // use the hash value from StringTable::hash_string() as it might use alternate hashcode.
123 return _shared_table.lookup((const char*)name,
124 java_lang_String::hash_code(name, len), len);
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 return l->literal();
135 }
136 }
137 }
138 // If the bucket size is too deep check if this hash code is insufficient.
139 if (count >= rehash_count && !needs_rehashing()) {
140 _needs_rehashing = check_rehash_table(count);
141 }
142 return NULL;
143 }
144
145
146 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
147 int len, unsigned int hashValue_arg, TRAPS) {
148
149 assert(java_lang_String::equals(string(), name, len),
150 "string must be properly initialized");
151 // Cannot hit a safepoint in this function because the "this" pointer can move.
152 NoSafepointVerifier nsv;
153
154 // Check if the symbol table has been rehashed, if so, need to recalculate
155 // the hash value and index before second lookup.
156 unsigned int hashValue;
157 int index;
158 if (use_alternate_hashcode()) {
159 hashValue = hash_string(name, len);
160 index = hash_to_index(hashValue);
161 } else {
162 hashValue = hashValue_arg;
163 index = index_arg;
164 }
165
166 // Since look-up was done lock-free, we need to check if another
167 // thread beat us in the race to insert the symbol.
168
169 // No need to lookup the shared table from here since the caller (intern()) already did
170 oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
171 if (test != NULL) {
172 // Entry already added
173 return test;
174 }
175
176 HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
177 add_entry(index, entry);
178 return string();
179 }
182 oop StringTable::lookup(Symbol* symbol) {
183 ResourceMark rm;
184 int length;
185 jchar* chars = symbol->as_unicode(length);
186 return lookup(chars, length);
187 }
188
189 // Tell the GC that this string was looked up in the StringTable.
190 static void ensure_string_alive(oop string) {
191 // A lookup in the StringTable could return an object that was previously
192 // considered dead. The SATB part of G1 needs to get notified about this
193 // potential resurrection, otherwise the marking might not find the object.
194 #if INCLUDE_ALL_GCS
195 if (UseG1GC && string != NULL) {
196 G1SATBCardTableModRefBS::enqueue(string);
197 }
198 #endif
199 }
200
201 oop StringTable::lookup(jchar* name, int len) {
202 oop string = lookup_shared(name, len);
203 if (string != NULL) {
204 return string;
205 }
206
207 unsigned int hash = hash_string(name, len);
208 int index = the_table()->hash_to_index(hash);
209 string = the_table()->lookup_in_main_table(index, name, len, hash);
210
211 ensure_string_alive(string);
212
213 return string;
214 }
215
216 oop StringTable::intern(Handle string_or_null, jchar* name,
217 int len, TRAPS) {
218 oop found_string = lookup_shared(name, len);
219 if (found_string != NULL) {
220 return found_string;
221 }
222
223 unsigned int hashValue = hash_string(name, len);
224 int index = the_table()->hash_to_index(hashValue);
225 found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
226
227 // Found
228 if (found_string != NULL) {
229 if (found_string != string_or_null()) {
230 ensure_string_alive(found_string);
231 }
232 return found_string;
233 }
234
235 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
236 assert(!Universe::heap()->is_in_reserved(name),
237 "proposed name of symbol must be stable");
238
239 Handle string;
240 // try to reuse the string if possible
241 if (!string_or_null.is_null()) {
242 string = string_or_null;
243 } else {
|
1 /*
2 * Copyright (c) 1997, 2017, 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 *
79 int check_size = sample(check_buf);
80 return (0 == memcmp(_save_buf, check_buf, check_size));
81 }
82
83 void set_region(const void* region) { _region = (address) region; }
84 };
85 #endif
86
87
88 // --------------------------------------------------------------------------
89 StringTable* StringTable::_the_table = NULL;
90 bool StringTable::_ignore_shared_strings = false;
91 bool StringTable::_needs_rehashing = false;
92
93 volatile int StringTable::_parallel_claimed_idx = 0;
94
95 CompactHashtable<oop, char> StringTable::_shared_table;
96
97 // Pick hashing algorithm
98 unsigned int StringTable::hash_string(const jchar* s, int len) {
99 return use_alternate_hashcode() ? alt_hash_string(s, len) :
100 java_lang_String::hash_code(s, len);
101 }
102
103 unsigned int StringTable::alt_hash_string(const jchar* s, int len) {
104 return AltHashing::murmur3_32(seed(), s, len);
105 }
106
107 unsigned int StringTable::hash_string(oop string) {
108 EXCEPTION_MARK;
109 if (string == NULL) {
110 return hash_string((jchar*)NULL, 0);
111 }
112 ResourceMark rm(THREAD);
113 // All String oops are hashed as unicode
114 int length;
115 jchar* chars = java_lang_String::as_unicode_string(string, length, THREAD);
116 if (chars != NULL) {
117 return hash_string(chars, length);
118 } else {
119 vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
120 return 0;
121 }
122 }
123
124 oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
125 assert(hash == java_lang_String::hash_code(name, len),
126 "hash must be computed using java_lang_String::hash_code");
127 return _shared_table.lookup((const char*)name, hash, len);
128 }
129
130 oop StringTable::lookup_in_main_table(int index, jchar* name,
131 int len, unsigned int hash) {
132 int count = 0;
133 for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
134 count++;
135 if (l->hash() == hash) {
136 if (java_lang_String::equals(l->literal(), name, len)) {
137 return l->literal();
138 }
139 }
140 }
141 // If the bucket size is too deep check if this hash code is insufficient.
142 if (count >= rehash_count && !needs_rehashing()) {
143 _needs_rehashing = check_rehash_table(count);
144 }
145 return NULL;
146 }
147
148
149 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
150 int len, unsigned int hashValue_arg, TRAPS) {
151
152 assert(java_lang_String::equals(string(), name, len),
153 "string must be properly initialized");
154 // Cannot hit a safepoint in this function because the "this" pointer can move.
155 NoSafepointVerifier nsv;
156
157 // Check if the symbol table has been rehashed, if so, need to recalculate
158 // the hash value and index before second lookup.
159 unsigned int hashValue;
160 int index;
161 if (use_alternate_hashcode()) {
162 hashValue = alt_hash_string(name, len);
163 index = hash_to_index(hashValue);
164 } else {
165 hashValue = hashValue_arg;
166 index = index_arg;
167 }
168
169 // Since look-up was done lock-free, we need to check if another
170 // thread beat us in the race to insert the symbol.
171
172 // No need to lookup the shared table from here since the caller (intern()) already did
173 oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
174 if (test != NULL) {
175 // Entry already added
176 return test;
177 }
178
179 HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
180 add_entry(index, entry);
181 return string();
182 }
185 oop StringTable::lookup(Symbol* symbol) {
186 ResourceMark rm;
187 int length;
188 jchar* chars = symbol->as_unicode(length);
189 return lookup(chars, length);
190 }
191
192 // Tell the GC that this string was looked up in the StringTable.
193 static void ensure_string_alive(oop string) {
194 // A lookup in the StringTable could return an object that was previously
195 // considered dead. The SATB part of G1 needs to get notified about this
196 // potential resurrection, otherwise the marking might not find the object.
197 #if INCLUDE_ALL_GCS
198 if (UseG1GC && string != NULL) {
199 G1SATBCardTableModRefBS::enqueue(string);
200 }
201 #endif
202 }
203
204 oop StringTable::lookup(jchar* name, int len) {
205 // shared table always uses java_lang_String::hash_code
206 unsigned int hash = java_lang_String::hash_code(name, len);
207 oop string = lookup_shared(name, len, hash);
208 if (string != NULL) {
209 return string;
210 }
211 if (use_alternate_hashcode()) {
212 hash = alt_hash_string(name, len);
213 }
214 int index = the_table()->hash_to_index(hash);
215 string = the_table()->lookup_in_main_table(index, name, len, hash);
216
217 ensure_string_alive(string);
218
219 return string;
220 }
221
222 oop StringTable::intern(Handle string_or_null, jchar* name,
223 int len, TRAPS) {
224 // shared table always uses java_lang_String::hash_code
225 unsigned int hashValue = java_lang_String::hash_code(name, len);
226 oop found_string = lookup_shared(name, len, hashValue);
227 if (found_string != NULL) {
228 return found_string;
229 }
230 if (use_alternate_hashcode()) {
231 hashValue = alt_hash_string(name, len);
232 }
233 int index = the_table()->hash_to_index(hashValue);
234 found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
235
236 // Found
237 if (found_string != NULL) {
238 if (found_string != string_or_null()) {
239 ensure_string_alive(found_string);
240 }
241 return found_string;
242 }
243
244 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
245 assert(!Universe::heap()->is_in_reserved(name),
246 "proposed name of symbol must be stable");
247
248 Handle string;
249 // try to reuse the string if possible
250 if (!string_or_null.is_null()) {
251 string = string_or_null;
252 } else {
|