Tue, 30 Oct 2012 10:23:55 -0700
8000988: VM deadlock when running btree006 on windows-i586
Reviewed-by: johnc, jcoomes, ysr
1 /*
2 * Copyright (c) 2002, 2010, 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 */
25 #ifndef SHARE_VM_MEMORY_HEAPINSPECTION_HPP
26 #define SHARE_VM_MEMORY_HEAPINSPECTION_HPP
28 #include "memory/allocation.inline.hpp"
29 #include "oops/oop.inline.hpp"
31 #if INCLUDE_SERVICES
34 // HeapInspection
36 // KlassInfoTable is a bucket hash table that
37 // maps Klass*s to extra information:
38 // instance count and instance word size.
39 //
40 // A KlassInfoBucket is the head of a link list
41 // of KlassInfoEntry's
42 //
43 // KlassInfoHisto is a growable array of pointers
44 // to KlassInfoEntry's and is used to sort
45 // the entries.
47 class KlassInfoEntry: public CHeapObj<mtInternal> {
48 private:
49 KlassInfoEntry* _next;
50 Klass* _klass;
51 long _instance_count;
52 size_t _instance_words;
54 public:
55 KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
56 _klass(k), _instance_count(0), _instance_words(0), _next(next)
57 {}
58 KlassInfoEntry* next() { return _next; }
59 bool is_equal(Klass* k) { return k == _klass; }
60 Klass* klass() { return _klass; }
61 long count() { return _instance_count; }
62 void set_count(long ct) { _instance_count = ct; }
63 size_t words() { return _instance_words; }
64 void set_words(size_t wds) { _instance_words = wds; }
65 int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
66 void print_on(outputStream* st) const;
67 };
69 class KlassInfoClosure: public StackObj {
70 public:
71 // Called for each KlassInfoEntry.
72 virtual void do_cinfo(KlassInfoEntry* cie) = 0;
73 };
75 class KlassInfoBucket: public CHeapObj<mtInternal> {
76 private:
77 KlassInfoEntry* _list;
78 KlassInfoEntry* list() { return _list; }
79 void set_list(KlassInfoEntry* l) { _list = l; }
80 public:
81 KlassInfoEntry* lookup(Klass* const k);
82 void initialize() { _list = NULL; }
83 void empty();
84 void iterate(KlassInfoClosure* cic);
85 };
87 class KlassInfoTable: public StackObj {
88 private:
89 int _size;
91 // An aligned reference address (typically the least
92 // address in the perm gen) used for hashing klass
93 // objects.
94 HeapWord* _ref;
96 KlassInfoBucket* _buckets;
97 uint hash(Klass* p);
98 KlassInfoEntry* lookup(Klass* const k);
100 public:
101 // Table size
102 enum {
103 cit_size = 20011
104 };
105 KlassInfoTable(int size, HeapWord* ref);
106 ~KlassInfoTable();
107 bool record_instance(const oop obj);
108 void iterate(KlassInfoClosure* cic);
109 bool allocation_failed() { return _buckets == NULL; }
110 };
112 class KlassInfoHisto : public StackObj {
113 private:
114 GrowableArray<KlassInfoEntry*>* _elements;
115 GrowableArray<KlassInfoEntry*>* elements() const { return _elements; }
116 const char* _title;
117 const char* title() const { return _title; }
118 static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2);
119 void print_elements(outputStream* st) const;
120 public:
121 enum {
122 histo_initial_size = 1000
123 };
124 KlassInfoHisto(const char* title,
125 int estimatedCount);
126 ~KlassInfoHisto();
127 void add(KlassInfoEntry* cie);
128 void print_on(outputStream* st) const;
129 void sort();
130 };
132 #endif // INCLUDE_SERVICES
134 class HeapInspection : public AllStatic {
135 public:
136 static void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
137 static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
138 };
140 #endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP