comparison src/share/vm/memory/heapInspection.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents d2a62e0f25eb
children 16fb9f942703 db9981fd3124
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "gc_interface/collectedHeap.hpp" 26 #include "gc_interface/collectedHeap.hpp"
27 #include "memory/genCollectedHeap.hpp" 27 #include "memory/genCollectedHeap.hpp"
28 #include "memory/heapInspection.hpp" 28 #include "memory/heapInspection.hpp"
29 #include "memory/resourceArea.hpp" 29 #include "memory/resourceArea.hpp"
30 #include "oops/klassOop.hpp"
31 #include "runtime/os.hpp" 30 #include "runtime/os.hpp"
32 #include "utilities/globalDefinitions.hpp" 31 #include "utilities/globalDefinitions.hpp"
33 #ifndef SERIALGC 32 #ifndef SERIALGC
34 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" 33 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
35 #endif 34 #endif
46 } 45 }
47 46
48 void KlassInfoEntry::print_on(outputStream* st) const { 47 void KlassInfoEntry::print_on(outputStream* st) const {
49 ResourceMark rm; 48 ResourceMark rm;
50 const char* name;; 49 const char* name;;
51 if (_klass->klass_part()->name() != NULL) { 50 if (_klass->name() != NULL) {
52 name = _klass->klass_part()->external_name(); 51 name = _klass->external_name();
53 } else { 52 } else {
54 if (_klass == Universe::klassKlassObj()) name = "<klassKlass>"; else
55 if (_klass == Universe::arrayKlassKlassObj()) name = "<arrayKlassKlass>"; else
56 if (_klass == Universe::objArrayKlassKlassObj()) name = "<objArrayKlassKlass>"; else
57 if (_klass == Universe::instanceKlassKlassObj()) name = "<instanceKlassKlass>"; else
58 if (_klass == Universe::typeArrayKlassKlassObj()) name = "<typeArrayKlassKlass>"; else
59 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else 53 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else
60 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else 54 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else
61 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else 55 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else
62 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else 56 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else
63 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else 57 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else
64 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else 58 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else
65 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else 59 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else
66 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else 60 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else
67 if (_klass == Universe::methodKlassObj()) name = "<methodKlass>"; else
68 if (_klass == Universe::constMethodKlassObj()) name = "<constMethodKlass>"; else
69 if (_klass == Universe::methodDataKlassObj()) name = "<methodDataKlass>"; else
70 if (_klass == Universe::constantPoolKlassObj()) name = "<constantPoolKlass>"; else
71 if (_klass == Universe::constantPoolCacheKlassObj()) name = "<constantPoolCacheKlass>"; else
72 if (_klass == Universe::compiledICHolderKlassObj()) name = "<compiledICHolderKlass>"; else
73 name = "<no name>"; 61 name = "<no name>";
74 } 62 }
75 // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit 63 // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
76 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", 64 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s",
77 (jlong) _instance_count, 65 (jlong) _instance_count,
78 (julong) _instance_words * HeapWordSize, 66 (julong) _instance_words * HeapWordSize,
79 name); 67 name);
80 } 68 }
81 69
82 KlassInfoEntry* KlassInfoBucket::lookup(const klassOop k) { 70 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
83 KlassInfoEntry* elt = _list; 71 KlassInfoEntry* elt = _list;
84 while (elt != NULL) { 72 while (elt != NULL) {
85 if (elt->is_equal(k)) { 73 if (elt->is_equal(k)) {
86 return elt; 74 return elt;
87 } 75 }
133 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal); 121 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal);
134 _size = 0; 122 _size = 0;
135 } 123 }
136 } 124 }
137 125
138 uint KlassInfoTable::hash(klassOop p) { 126 uint KlassInfoTable::hash(Klass* p) {
139 assert(Universe::heap()->is_in_permanent((HeapWord*)p), "all klasses in permgen"); 127 assert(p->is_metadata(), "all klasses are metadata");
140 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2); 128 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
141 } 129 }
142 130
143 KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) { 131 KlassInfoEntry* KlassInfoTable::lookup(Klass* const k) {
144 uint idx = hash(k) % _size; 132 uint idx = hash(k) % _size;
145 assert(_buckets != NULL, "Allocation failure should have been caught"); 133 assert(_buckets != NULL, "Allocation failure should have been caught");
146 KlassInfoEntry* e = _buckets[idx].lookup(k); 134 KlassInfoEntry* e = _buckets[idx].lookup(k);
147 // Lookup may fail if this is a new klass for which we 135 // Lookup may fail if this is a new klass for which we
148 // could not allocate space for an new entry. 136 // could not allocate space for an new entry.
151 } 139 }
152 140
153 // Return false if the entry could not be recorded on account 141 // Return false if the entry could not be recorded on account
154 // of running out of space required to create a new entry. 142 // of running out of space required to create a new entry.
155 bool KlassInfoTable::record_instance(const oop obj) { 143 bool KlassInfoTable::record_instance(const oop obj) {
156 klassOop k = obj->klass(); 144 Klass* k = obj->klass();
157 KlassInfoEntry* elt = lookup(k); 145 KlassInfoEntry* elt = lookup(k);
158 // elt may be NULL if it's a new klass for which we 146 // elt may be NULL if it's a new klass for which we
159 // could not allocate space for a new entry in the hashtable. 147 // could not allocate space for a new entry in the hashtable.
160 if (elt != NULL) { 148 if (elt != NULL) {
161 elt->set_count(elt->count() + 1); 149 elt->set_count(elt->count() + 1);
241 size_t missed_count() { return _missed_count; } 229 size_t missed_count() { return _missed_count; }
242 }; 230 };
243 231
244 void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) { 232 void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
245 ResourceMark rm; 233 ResourceMark rm;
246 HeapWord* ref; 234 // Get some random number for ref (the hash key)
247 235 HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj();
248 CollectedHeap* heap = Universe::heap(); 236 CollectedHeap* heap = Universe::heap();
249 bool is_shared_heap = false; 237 bool is_shared_heap = false;
250 switch (heap->kind()) { 238
251 case CollectedHeap::G1CollectedHeap:
252 case CollectedHeap::GenCollectedHeap: {
253 is_shared_heap = true;
254 SharedHeap* sh = (SharedHeap*)heap;
255 if (need_prologue) {
256 sh->gc_prologue(false /* !full */); // get any necessary locks, etc.
257 }
258 ref = sh->perm_gen()->used_region().start();
259 break;
260 }
261 #ifndef SERIALGC
262 case CollectedHeap::ParallelScavengeHeap: {
263 ParallelScavengeHeap* psh = (ParallelScavengeHeap*)heap;
264 ref = psh->perm_gen()->object_space()->used_region().start();
265 break;
266 }
267 #endif // SERIALGC
268 default:
269 ShouldNotReachHere(); // Unexpected heap kind for this op
270 }
271 // Collect klass instance info 239 // Collect klass instance info
272 KlassInfoTable cit(KlassInfoTable::cit_size, ref); 240 KlassInfoTable cit(KlassInfoTable::cit_size, ref);
273 if (!cit.allocation_failed()) { 241 if (!cit.allocation_failed()) {
274 // Iterate over objects in the heap 242 // Iterate over objects in the heap
275 RecordInstanceClosure ric(&cit); 243 RecordInstanceClosure ric(&cit);
276 // If this operation encounters a bad object when using CMS,
277 // consider using safe_object_iterate() which avoids perm gen
278 // objects that may contain bad references.
279 Universe::heap()->object_iterate(&ric); 244 Universe::heap()->object_iterate(&ric);
280 245
281 // Report if certain classes are not counted because of 246 // Report if certain classes are not counted because of
282 // running out of C-heap for the histogram. 247 // running out of C-heap for the histogram.
283 size_t missed_count = ric.missed_count(); 248 size_t missed_count = ric.missed_count();
306 } 271 }
307 } 272 }
308 273
309 class FindInstanceClosure : public ObjectClosure { 274 class FindInstanceClosure : public ObjectClosure {
310 private: 275 private:
311 klassOop _klass; 276 Klass* _klass;
312 GrowableArray<oop>* _result; 277 GrowableArray<oop>* _result;
313 278
314 public: 279 public:
315 FindInstanceClosure(klassOop k, GrowableArray<oop>* result) : _klass(k), _result(result) {}; 280 FindInstanceClosure(Klass* k, GrowableArray<oop>* result) : _klass(k), _result(result) {};
316 281
317 void do_object(oop obj) { 282 void do_object(oop obj) {
318 if (obj->is_a(_klass)) { 283 if (obj->is_a(_klass)) {
319 _result->append(obj); 284 _result->append(obj);
320 } 285 }
321 } 286 }
322 }; 287 };
323 288
324 void HeapInspection::find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result) { 289 void HeapInspection::find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) {
325 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped"); 290 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
326 assert(Heap_lock->is_locked(), "should have the Heap_lock"); 291 assert(Heap_lock->is_locked(), "should have the Heap_lock");
327 292
328 // Ensure that the heap is parsable 293 // Ensure that the heap is parsable
329 Universe::heap()->ensure_parsability(false); // no need to retire TALBs 294 Universe::heap()->ensure_parsability(false); // no need to retire TALBs
330 295
331 // Iterate over objects in the heap 296 // Iterate over objects in the heap
332 FindInstanceClosure fic(k, result); 297 FindInstanceClosure fic(k, result);
333 // If this operation encounters a bad object when using CMS, 298 // If this operation encounters a bad object when using CMS,
334 // consider using safe_object_iterate() which avoids perm gen 299 // consider using safe_object_iterate() which avoids metadata
335 // objects that may contain bad references. 300 // objects that may contain bad references.
336 Universe::heap()->object_iterate(&fic); 301 Universe::heap()->object_iterate(&fic);
337 } 302 }