20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/altHashing.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "gc_interface/collectedHeap.inline.hpp"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/filemap.hpp"
33 #include "memory/gcLocker.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/oop.inline2.hpp"
36 #include "runtime/atomic.inline.hpp"
37 #include "runtime/mutexLocker.hpp"
38 #include "utilities/hashtable.inline.hpp"
39 #if INCLUDE_ALL_GCS
40 #include "gc_implementation/g1/g1StringDedup.hpp"
41 #endif
42
43 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
44
45 // the number of buckets a thread claims
46 const int ClaimChunkSize = 32;
47
48 #ifdef ASSERT
49 class StableMemoryChecker : public StackObj {
50 enum { _bufsize = wordSize*4 };
51
52 address _region;
53 jint _size;
54 u1 _save_buf[_bufsize];
55
56 int sample(u1* save_buf) {
57 if (_size <= _bufsize) {
58 memcpy(save_buf, _region, _size);
59 return _size;
140
141 oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
142 if (test != NULL) {
143 // Entry already added
144 return test;
145 }
146
147 HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
148 add_entry(index, entry);
149 return string();
150 }
151
152
153 oop StringTable::lookup(Symbol* symbol) {
154 ResourceMark rm;
155 int length;
156 jchar* chars = symbol->as_unicode(length);
157 return lookup(chars, length);
158 }
159
160
161 oop StringTable::lookup(jchar* name, int len) {
162 unsigned int hash = hash_string(name, len);
163 int index = the_table()->hash_to_index(hash);
164 return the_table()->lookup(index, name, len, hash);
165 }
166
167
168 oop StringTable::intern(Handle string_or_null, jchar* name,
169 int len, TRAPS) {
170 unsigned int hashValue = hash_string(name, len);
171 int index = the_table()->hash_to_index(hashValue);
172 oop found_string = the_table()->lookup(index, name, len, hashValue);
173
174 // Found
175 if (found_string != NULL) return found_string;
176
177 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
178 assert(!Universe::heap()->is_in_reserved(name),
179 "proposed name of symbol must be stable");
180
181 Handle string;
182 // try to reuse the string if possible
183 if (!string_or_null.is_null()) {
184 string = string_or_null;
185 } else {
186 string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
187 }
188
189 #if INCLUDE_ALL_GCS
190 if (G1StringDedup::is_enabled()) {
191 // Deduplicate the string before it is interned. Note that we should never
192 // deduplicate a string after it has been interned. Doing so will counteract
193 // compiler optimizations done on e.g. interned string literals.
194 G1StringDedup::deduplicate(string());
195 }
196 #endif
197
198 // Grab the StringTable_lock before getting the_table() because it could
199 // change at safepoint.
200 MutexLocker ml(StringTable_lock, THREAD);
201
202 // Otherwise, add to symbol to table
203 return the_table()->basic_add(index, string, name, len,
204 hashValue, CHECK_NULL);
205 }
206
207 oop StringTable::intern(Symbol* symbol, TRAPS) {
208 if (symbol == NULL) return NULL;
209 ResourceMark rm(THREAD);
210 int length;
211 jchar* chars = symbol->as_unicode(length);
212 Handle string;
213 oop result = intern(string, chars, length, CHECK_NULL);
214 return result;
215 }
216
217
218 oop StringTable::intern(oop string, TRAPS)
219 {
220 if (string == NULL) return NULL;
221 ResourceMark rm(THREAD);
222 int length;
223 Handle h_string (THREAD, string);
224 jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/altHashing.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "gc_interface/collectedHeap.inline.hpp"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/filemap.hpp"
33 #include "memory/gcLocker.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/oop.inline2.hpp"
36 #include "runtime/atomic.inline.hpp"
37 #include "runtime/mutexLocker.hpp"
38 #include "utilities/hashtable.inline.hpp"
39 #if INCLUDE_ALL_GCS
40 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
41 #include "gc_implementation/g1/g1StringDedup.hpp"
42 #endif
43
44 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
45
46 // the number of buckets a thread claims
47 const int ClaimChunkSize = 32;
48
49 #ifdef ASSERT
50 class StableMemoryChecker : public StackObj {
51 enum { _bufsize = wordSize*4 };
52
53 address _region;
54 jint _size;
55 u1 _save_buf[_bufsize];
56
57 int sample(u1* save_buf) {
58 if (_size <= _bufsize) {
59 memcpy(save_buf, _region, _size);
60 return _size;
141
142 oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
143 if (test != NULL) {
144 // Entry already added
145 return test;
146 }
147
148 HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
149 add_entry(index, entry);
150 return string();
151 }
152
153
154 oop StringTable::lookup(Symbol* symbol) {
155 ResourceMark rm;
156 int length;
157 jchar* chars = symbol->as_unicode(length);
158 return lookup(chars, length);
159 }
160
161 // Tell the GC that this string was looked up in the StringTable.
162 static void ensure_string_alive(oop string) {
163 // A lookup in the StringTable could return an object that was previously
164 // considered dead. The SATB part of G1 needs to get notified about this
165 // potential resurrection, otherwise the marking might not find the object.
166 #if INCLUDE_ALL_GCS
167 if (UseG1GC && string != NULL) {
168 G1SATBCardTableModRefBS::enqueue(string);
169 }
170 #endif
171 }
172
173 oop StringTable::lookup(jchar* name, int len) {
174 unsigned int hash = hash_string(name, len);
175 int index = the_table()->hash_to_index(hash);
176 oop string = the_table()->lookup(index, name, len, hash);
177
178 ensure_string_alive(string);
179
180 return string;
181 }
182
183
184 oop StringTable::intern(Handle string_or_null, jchar* name,
185 int len, TRAPS) {
186 unsigned int hashValue = hash_string(name, len);
187 int index = the_table()->hash_to_index(hashValue);
188 oop found_string = the_table()->lookup(index, name, len, hashValue);
189
190 // Found
191 if (found_string != NULL) {
192 ensure_string_alive(found_string);
193 return found_string;
194 }
195
196 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
197 assert(!Universe::heap()->is_in_reserved(name),
198 "proposed name of symbol must be stable");
199
200 Handle string;
201 // try to reuse the string if possible
202 if (!string_or_null.is_null()) {
203 string = string_or_null;
204 } else {
205 string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
206 }
207
208 #if INCLUDE_ALL_GCS
209 if (G1StringDedup::is_enabled()) {
210 // Deduplicate the string before it is interned. Note that we should never
211 // deduplicate a string after it has been interned. Doing so will counteract
212 // compiler optimizations done on e.g. interned string literals.
213 G1StringDedup::deduplicate(string());
214 }
215 #endif
216
217 // Grab the StringTable_lock before getting the_table() because it could
218 // change at safepoint.
219 oop added_or_found;
220 {
221 MutexLocker ml(StringTable_lock, THREAD);
222 // Otherwise, add to symbol to table
223 added_or_found = the_table()->basic_add(index, string, name, len,
224 hashValue, CHECK_NULL);
225 }
226
227 ensure_string_alive(added_or_found);
228
229 return added_or_found;
230 }
231
232 oop StringTable::intern(Symbol* symbol, TRAPS) {
233 if (symbol == NULL) return NULL;
234 ResourceMark rm(THREAD);
235 int length;
236 jchar* chars = symbol->as_unicode(length);
237 Handle string;
238 oop result = intern(string, chars, length, CHECK_NULL);
239 return result;
240 }
241
242
243 oop StringTable::intern(oop string, TRAPS)
244 {
245 if (string == NULL) return NULL;
246 ResourceMark rm(THREAD);
247 int length;
248 Handle h_string (THREAD, string);
249 jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);
|