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 #include "precompiled.hpp"
26 #include "classfile/altHashing.hpp"
27 #include "classfile/dictionary.hpp"
28 #include "classfile/javaClasses.inline.hpp"
29 #include "classfile/moduleEntry.hpp"
30 #include "classfile/packageEntry.hpp"
31 #include "classfile/protectionDomainCache.hpp"
32 #include "classfile/stringTable.hpp"
33 #include "memory/allocation.inline.hpp"
34 #include "memory/filemap.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "runtime/safepoint.hpp"
38 #include "utilities/dtrace.hpp"
39 #include "utilities/hashtable.hpp"
40 #include "utilities/hashtable.inline.hpp"
41 #include "utilities/numberSeq.hpp"
42
43
44 // This hashtable is implemented as an open hash table with a fixed number of buckets.
45
46 template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry_free_list() {
47 BasicHashtableEntry<F>* entry = NULL;
48 if (_free_list != NULL) {
49 entry = _free_list;
50 _free_list = _free_list->next();
51 }
52 return entry;
53 }
54
171 template <MEMFLAGS F> void BasicHashtable<F>::bulk_free_entries(BucketUnlinkContext* context) {
172 if (context->_num_removed == 0) {
173 assert(context->_removed_head == NULL && context->_removed_tail == NULL,
174 "Zero entries in the unlink context, but elements linked from " PTR_FORMAT " to " PTR_FORMAT,
175 p2i(context->_removed_head), p2i(context->_removed_tail));
176 return;
177 }
178
179 // MT-safe add of the list of BasicHashTableEntrys from the context to the free list.
180 BasicHashtableEntry<F>* current = _free_list;
181 while (true) {
182 context->_removed_tail->set_next(current);
183 BasicHashtableEntry<F>* old = (BasicHashtableEntry<F>*)Atomic::cmpxchg_ptr(context->_removed_head, &_free_list, current);
184 if (old == current) {
185 break;
186 }
187 current = old;
188 }
189 Atomic::add(-context->_num_removed, &_number_of_entries);
190 }
191
192 // Copy the table to the shared space.
193
194 template <MEMFLAGS F> void BasicHashtable<F>::copy_table(char** top, char* end) {
195
196 // Dump the hash table entries.
197
198 intptr_t *plen = (intptr_t*)(*top);
199 *top += sizeof(*plen);
200
201 int i;
202 for (i = 0; i < _table_size; ++i) {
203 for (BasicHashtableEntry<F>** p = _buckets[i].entry_addr();
204 *p != NULL;
205 p = (*p)->next_addr()) {
206 if (*top + entry_size() > end) {
207 report_out_of_shared_space(SharedMiscData);
208 }
209 *p = (BasicHashtableEntry<F>*)memcpy(*top, *p, entry_size());
210 *top += entry_size();
211 }
212 }
213 *plen = (char*)(*top) - (char*)plen - sizeof(*plen);
214
215 // Set the shared bit.
216
217 for (i = 0; i < _table_size; ++i) {
218 for (BasicHashtableEntry<F>* p = bucket(i); p != NULL; p = p->next()) {
219 p->set_shared();
220 }
221 }
222 }
223
224 template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(Symbol *symbol) {
225 return symbol->size() * HeapWordSize;
226 }
227
228 template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(oop oop) {
229 // NOTE: this would over-count if (pre-JDK8) java_lang_Class::has_offset_field() is true,
230 // and the String.value array is shared by several Strings. However, starting from JDK8,
231 // the String.value array is not shared anymore.
232 assert(oop != NULL && oop->klass() == SystemDictionary::String_klass(), "only strings are supported");
233 return (oop->size() + java_lang_String::value(oop)->size()) * HeapWordSize;
234 }
258 int total_bytes = literal_bytes + bucket_bytes + entry_bytes;
259
260 double bucket_avg = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets);
261 double entry_avg = (num_entries <= 0) ? 0 : (entry_bytes / num_entries);
262 double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries);
263
264 st->print_cr("%s statistics:", table_name);
265 st->print_cr("Number of buckets : %9d = %9d bytes, avg %7.3f", (int)num_buckets, bucket_bytes, bucket_avg);
266 st->print_cr("Number of entries : %9d = %9d bytes, avg %7.3f", (int)num_entries, entry_bytes, entry_avg);
267 st->print_cr("Number of literals : %9d = %9d bytes, avg %7.3f", (int)num_entries, literal_bytes, literal_avg);
268 st->print_cr("Total footprint : %9s = %9d bytes", "", total_bytes);
269 st->print_cr("Average bucket size : %9.3f", summary.avg());
270 st->print_cr("Variance of bucket size : %9.3f", summary.variance());
271 st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
272 st->print_cr("Maximum bucket size : %9d", (int)summary.maximum());
273 }
274
275
276 // Dump the hash table buckets.
277
278 template <MEMFLAGS F> void BasicHashtable<F>::copy_buckets(char** top, char* end) {
279 intptr_t len = _table_size * sizeof(HashtableBucket<F>);
280 *(intptr_t*)(*top) = len;
281 *top += sizeof(intptr_t);
282
283 *(intptr_t*)(*top) = _number_of_entries;
284 *top += sizeof(intptr_t);
285
286 if (*top + len > end) {
287 report_out_of_shared_space(SharedMiscData);
288 }
289 _buckets = (HashtableBucket<F>*)memcpy(*top, _buckets, len);
290 *top += len;
291 }
292
293
294 #ifndef PRODUCT
295
296 template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
297 ResourceMark rm;
298
299 for (int i = 0; i < BasicHashtable<F>::table_size(); i++) {
300 HashtableEntry<T, F>* entry = bucket(i);
301 while(entry != NULL) {
302 tty->print("%d : ", i);
303 entry->literal()->print();
304 tty->cr();
305 entry = entry->next();
306 }
307 }
308 }
309
310
347 template class Hashtable<nmethod*, mtGC>;
348 template class HashtableEntry<nmethod*, mtGC>;
349 template class BasicHashtable<mtGC>;
350 #endif
351 template class Hashtable<ConstantPool*, mtClass>;
352 template class RehashableHashtable<Symbol*, mtSymbol>;
353 template class RehashableHashtable<oopDesc*, mtSymbol>;
354 template class Hashtable<Symbol*, mtSymbol>;
355 template class Hashtable<Klass*, mtClass>;
356 template class Hashtable<InstanceKlass*, mtClass>;
357 template class Hashtable<oop, mtClass>;
358 #if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
359 template class Hashtable<oop, mtSymbol>;
360 template class RehashableHashtable<oop, mtSymbol>;
361 #endif // SOLARIS || CHECK_UNHANDLED_OOPS
362 template class Hashtable<oopDesc*, mtSymbol>;
363 template class Hashtable<Symbol*, mtClass>;
364 template class HashtableEntry<Symbol*, mtSymbol>;
365 template class HashtableEntry<Symbol*, mtClass>;
366 template class HashtableEntry<oop, mtSymbol>;
367 template class BasicHashtableEntry<mtSymbol>;
368 template class BasicHashtableEntry<mtCode>;
369 template class BasicHashtable<mtClass>;
370 template class BasicHashtable<mtClassShared>;
371 template class BasicHashtable<mtSymbol>;
372 template class BasicHashtable<mtCode>;
373 template class BasicHashtable<mtInternal>;
374 template class BasicHashtable<mtModule>;
375 #if INCLUDE_TRACE
376 template class Hashtable<Symbol*, mtTracing>;
377 template class HashtableEntry<Symbol*, mtTracing>;
378 template class BasicHashtable<mtTracing>;
379 #endif
380 template class BasicHashtable<mtCompiler>;
381
382 template void BasicHashtable<mtClass>::verify_table<DictionaryEntry>(char const*);
383 template void BasicHashtable<mtModule>::verify_table<ModuleEntry>(char const*);
384 template void BasicHashtable<mtModule>::verify_table<PackageEntry>(char const*);
385 template void BasicHashtable<mtClass>::verify_table<ProtectionDomainCacheEntry>(char const*);
|
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 #include "precompiled.hpp"
26 #include "classfile/altHashing.hpp"
27 #include "classfile/dictionary.hpp"
28 #include "classfile/javaClasses.inline.hpp"
29 #include "classfile/moduleEntry.hpp"
30 #include "classfile/packageEntry.hpp"
31 #include "classfile/protectionDomainCache.hpp"
32 #include "classfile/stringTable.hpp"
33 #include "memory/allocation.inline.hpp"
34 #include "memory/filemap.hpp"
35 #include "memory/metaspaceShared.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "runtime/safepoint.hpp"
39 #include "utilities/dtrace.hpp"
40 #include "utilities/hashtable.hpp"
41 #include "utilities/hashtable.inline.hpp"
42 #include "utilities/numberSeq.hpp"
43
44
45 // This hashtable is implemented as an open hash table with a fixed number of buckets.
46
47 template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry_free_list() {
48 BasicHashtableEntry<F>* entry = NULL;
49 if (_free_list != NULL) {
50 entry = _free_list;
51 _free_list = _free_list->next();
52 }
53 return entry;
54 }
55
172 template <MEMFLAGS F> void BasicHashtable<F>::bulk_free_entries(BucketUnlinkContext* context) {
173 if (context->_num_removed == 0) {
174 assert(context->_removed_head == NULL && context->_removed_tail == NULL,
175 "Zero entries in the unlink context, but elements linked from " PTR_FORMAT " to " PTR_FORMAT,
176 p2i(context->_removed_head), p2i(context->_removed_tail));
177 return;
178 }
179
180 // MT-safe add of the list of BasicHashTableEntrys from the context to the free list.
181 BasicHashtableEntry<F>* current = _free_list;
182 while (true) {
183 context->_removed_tail->set_next(current);
184 BasicHashtableEntry<F>* old = (BasicHashtableEntry<F>*)Atomic::cmpxchg_ptr(context->_removed_head, &_free_list, current);
185 if (old == current) {
186 break;
187 }
188 current = old;
189 }
190 Atomic::add(-context->_num_removed, &_number_of_entries);
191 }
192 // Copy the table to the shared space.
193 template <MEMFLAGS F> size_t BasicHashtable<F>::count_bytes_for_table() {
194 size_t bytes = 0;
195 bytes += sizeof(intptr_t); // len
196
197 for (int i = 0; i < _table_size; ++i) {
198 for (BasicHashtableEntry<F>** p = _buckets[i].entry_addr();
199 *p != NULL;
200 p = (*p)->next_addr()) {
201 bytes += entry_size();
202 }
203 }
204
205 return bytes;
206 }
207
208 // Dump the hash table entries (into CDS archive)
209 template <MEMFLAGS F> void BasicHashtable<F>::copy_table(char* top, char* end) {
210 assert(is_ptr_aligned(top, sizeof(intptr_t)), "bad alignment");
211 intptr_t *plen = (intptr_t*)(top);
212 top += sizeof(*plen);
213
214 int i;
215 for (i = 0; i < _table_size; ++i) {
216 for (BasicHashtableEntry<F>** p = _buckets[i].entry_addr();
217 *p != NULL;
218 p = (*p)->next_addr()) {
219 *p = (BasicHashtableEntry<F>*)memcpy(top, *p, entry_size());
220 top += entry_size();
221 }
222 }
223 *plen = (char*)(top) - (char*)plen - sizeof(*plen);
224 assert(top == end, "count_bytes_for_table is wrong");
225 // Set the shared bit.
226
227 for (i = 0; i < _table_size; ++i) {
228 for (BasicHashtableEntry<F>* p = bucket(i); p != NULL; p = p->next()) {
229 p->set_shared();
230 }
231 }
232 }
233
234 template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(Symbol *symbol) {
235 return symbol->size() * HeapWordSize;
236 }
237
238 template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(oop oop) {
239 // NOTE: this would over-count if (pre-JDK8) java_lang_Class::has_offset_field() is true,
240 // and the String.value array is shared by several Strings. However, starting from JDK8,
241 // the String.value array is not shared anymore.
242 assert(oop != NULL && oop->klass() == SystemDictionary::String_klass(), "only strings are supported");
243 return (oop->size() + java_lang_String::value(oop)->size()) * HeapWordSize;
244 }
268 int total_bytes = literal_bytes + bucket_bytes + entry_bytes;
269
270 double bucket_avg = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets);
271 double entry_avg = (num_entries <= 0) ? 0 : (entry_bytes / num_entries);
272 double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries);
273
274 st->print_cr("%s statistics:", table_name);
275 st->print_cr("Number of buckets : %9d = %9d bytes, avg %7.3f", (int)num_buckets, bucket_bytes, bucket_avg);
276 st->print_cr("Number of entries : %9d = %9d bytes, avg %7.3f", (int)num_entries, entry_bytes, entry_avg);
277 st->print_cr("Number of literals : %9d = %9d bytes, avg %7.3f", (int)num_entries, literal_bytes, literal_avg);
278 st->print_cr("Total footprint : %9s = %9d bytes", "", total_bytes);
279 st->print_cr("Average bucket size : %9.3f", summary.avg());
280 st->print_cr("Variance of bucket size : %9.3f", summary.variance());
281 st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
282 st->print_cr("Maximum bucket size : %9d", (int)summary.maximum());
283 }
284
285
286 // Dump the hash table buckets.
287
288 template <MEMFLAGS F> size_t BasicHashtable<F>::count_bytes_for_buckets() {
289 size_t bytes = 0;
290 bytes += sizeof(intptr_t); // len
291 bytes += sizeof(intptr_t); // _number_of_entries
292 bytes += _table_size * sizeof(HashtableBucket<F>); // the buckets
293
294 return bytes;
295 }
296
297 // Dump the buckets (into CDS archive)
298 template <MEMFLAGS F> void BasicHashtable<F>::copy_buckets(char* top, char* end) {
299 assert(is_ptr_aligned(top, sizeof(intptr_t)), "bad alignment");
300 intptr_t len = _table_size * sizeof(HashtableBucket<F>);
301 *(intptr_t*)(top) = len;
302 top += sizeof(intptr_t);
303
304 *(intptr_t*)(top) = _number_of_entries;
305 top += sizeof(intptr_t);
306
307 _buckets = (HashtableBucket<F>*)memcpy(top, _buckets, len);
308 top += len;
309
310 assert(top == end, "count_bytes_for_buckets is wrong");
311 }
312
313
314 #ifndef PRODUCT
315
316 template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
317 ResourceMark rm;
318
319 for (int i = 0; i < BasicHashtable<F>::table_size(); i++) {
320 HashtableEntry<T, F>* entry = bucket(i);
321 while(entry != NULL) {
322 tty->print("%d : ", i);
323 entry->literal()->print();
324 tty->cr();
325 entry = entry->next();
326 }
327 }
328 }
329
330
367 template class Hashtable<nmethod*, mtGC>;
368 template class HashtableEntry<nmethod*, mtGC>;
369 template class BasicHashtable<mtGC>;
370 #endif
371 template class Hashtable<ConstantPool*, mtClass>;
372 template class RehashableHashtable<Symbol*, mtSymbol>;
373 template class RehashableHashtable<oopDesc*, mtSymbol>;
374 template class Hashtable<Symbol*, mtSymbol>;
375 template class Hashtable<Klass*, mtClass>;
376 template class Hashtable<InstanceKlass*, mtClass>;
377 template class Hashtable<oop, mtClass>;
378 #if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
379 template class Hashtable<oop, mtSymbol>;
380 template class RehashableHashtable<oop, mtSymbol>;
381 #endif // SOLARIS || CHECK_UNHANDLED_OOPS
382 template class Hashtable<oopDesc*, mtSymbol>;
383 template class Hashtable<Symbol*, mtClass>;
384 template class HashtableEntry<Symbol*, mtSymbol>;
385 template class HashtableEntry<Symbol*, mtClass>;
386 template class HashtableEntry<oop, mtSymbol>;
387 template class HashtableBucket<mtClass>;
388 template class BasicHashtableEntry<mtSymbol>;
389 template class BasicHashtableEntry<mtCode>;
390 template class BasicHashtable<mtClass>;
391 template class BasicHashtable<mtClassShared>;
392 template class BasicHashtable<mtSymbol>;
393 template class BasicHashtable<mtCode>;
394 template class BasicHashtable<mtInternal>;
395 template class BasicHashtable<mtModule>;
396 #if INCLUDE_TRACE
397 template class Hashtable<Symbol*, mtTracing>;
398 template class HashtableEntry<Symbol*, mtTracing>;
399 template class BasicHashtable<mtTracing>;
400 #endif
401 template class BasicHashtable<mtCompiler>;
402
403 template void BasicHashtable<mtClass>::verify_table<DictionaryEntry>(char const*);
404 template void BasicHashtable<mtModule>::verify_table<ModuleEntry>(char const*);
405 template void BasicHashtable<mtModule>::verify_table<PackageEntry>(char const*);
406 template void BasicHashtable<mtClass>::verify_table<ProtectionDomainCacheEntry>(char const*);
|