heapInspection.hpp revision 1472:c18cbe5936b8
1/* 2 * Copyright (c) 2002, 2008, 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 * 23 */ 24 25#ifndef SERVICES_KERNEL 26 27 28// HeapInspection 29 30// KlassInfoTable is a bucket hash table that 31// maps klassOops to extra information: 32// instance count and instance word size. 33// 34// A KlassInfoBucket is the head of a link list 35// of KlassInfoEntry's 36// 37// KlassInfoHisto is a growable array of pointers 38// to KlassInfoEntry's and is used to sort 39// the entries. 40 41class KlassInfoEntry: public CHeapObj { 42 private: 43 KlassInfoEntry* _next; 44 klassOop _klass; 45 long _instance_count; 46 size_t _instance_words; 47 48 public: 49 KlassInfoEntry(klassOop k, KlassInfoEntry* next) : 50 _klass(k), _instance_count(0), _instance_words(0), _next(next) 51 {} 52 KlassInfoEntry* next() { return _next; } 53 bool is_equal(klassOop k) { return k == _klass; } 54 klassOop klass() { return _klass; } 55 long count() { return _instance_count; } 56 void set_count(long ct) { _instance_count = ct; } 57 size_t words() { return _instance_words; } 58 void set_words(size_t wds) { _instance_words = wds; } 59 int compare(KlassInfoEntry* e1, KlassInfoEntry* e2); 60 void print_on(outputStream* st) const; 61}; 62 63class KlassInfoClosure: public StackObj { 64 public: 65 // Called for each KlassInfoEntry. 66 virtual void do_cinfo(KlassInfoEntry* cie) = 0; 67}; 68 69class KlassInfoBucket: public CHeapObj { 70 private: 71 KlassInfoEntry* _list; 72 KlassInfoEntry* list() { return _list; } 73 void set_list(KlassInfoEntry* l) { _list = l; } 74 public: 75 KlassInfoEntry* lookup(const klassOop k); 76 void initialize() { _list = NULL; } 77 void empty(); 78 void iterate(KlassInfoClosure* cic); 79}; 80 81class KlassInfoTable: public StackObj { 82 private: 83 int _size; 84 85 // An aligned reference address (typically the least 86 // address in the perm gen) used for hashing klass 87 // objects. 88 HeapWord* _ref; 89 90 KlassInfoBucket* _buckets; 91 uint hash(klassOop p); 92 KlassInfoEntry* lookup(const klassOop k); 93 94 public: 95 // Table size 96 enum { 97 cit_size = 20011 98 }; 99 KlassInfoTable(int size, HeapWord* ref); 100 ~KlassInfoTable(); 101 bool record_instance(const oop obj); 102 void iterate(KlassInfoClosure* cic); 103 bool allocation_failed() { return _buckets == NULL; } 104}; 105 106class KlassInfoHisto : public StackObj { 107 private: 108 GrowableArray<KlassInfoEntry*>* _elements; 109 GrowableArray<KlassInfoEntry*>* elements() const { return _elements; } 110 const char* _title; 111 const char* title() const { return _title; } 112 static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2); 113 void print_elements(outputStream* st) const; 114 public: 115 enum { 116 histo_initial_size = 1000 117 }; 118 KlassInfoHisto(const char* title, 119 int estimatedCount); 120 ~KlassInfoHisto(); 121 void add(KlassInfoEntry* cie); 122 void print_on(outputStream* st) const; 123 void sort(); 124}; 125 126#endif // SERVICES_KERNEL 127 128class HeapInspection : public AllStatic { 129 public: 130 static void heap_inspection(outputStream* st, bool need_prologue) KERNEL_RETURN; 131 static void find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result) KERNEL_RETURN; 132}; 133