annotate agent/src/share/classes/sun/jvm/hotspot/utilities/BitMap.java @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents a61af66fc99e
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.utilities;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import sun.jvm.hotspot.debugger.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 /** Manages a bitmap of the specified bit size */
a61af66fc99e Initial load
duke
parents:
diff changeset
30 public class BitMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
31 public BitMap(int sizeInBits) {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 this.size = sizeInBits;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 int nofWords = sizeInWords();
a61af66fc99e Initial load
duke
parents:
diff changeset
34 data = new int[nofWords];
a61af66fc99e Initial load
duke
parents:
diff changeset
35 }
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 public int size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
38 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 }
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
42 public boolean at(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 Assert.that(offset>=0 && offset < size(), "BitMap index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46 return Bits.isSetNthBit(wordFor(offset), offset % bitsPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 public void atPut(int offset, boolean value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 int index = indexFor(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
51 int pos = offset % bitsPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 if (value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 data[index] = Bits.setNthBit(data[index], pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
54 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 data[index] = Bits.clearNthBit(data[index], pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 public void set_size(int value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 size = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 public void set_map(Address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 for (int i=0; i<sizeInWords(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 data[i] = (int) addr.getCIntegerAt(0, bytesPerWord, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 addr = addr.addOffsetTo(bytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 public void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 for (int i = 0; i < sizeInWords(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 data[i] = Bits.NoBits;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 public void iterate(BitMapClosure blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 for (int index = 0; index < sizeInWords(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 int rest = data[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
80 for (int offset = index * bitsPerWord; rest != Bits.NoBits; offset++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
81 if (rest % 2 == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 if (offset < size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 blk.doBit(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return; // Passed end of map
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88 rest = rest >>> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 }
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 /** Sets this bitmap to the logical union of it and the
a61af66fc99e Initial load
duke
parents:
diff changeset
94 argument. Both bitmaps must be the same size. Returns true if a
a61af66fc99e Initial load
duke
parents:
diff changeset
95 change was caused in this bitmap. */
a61af66fc99e Initial load
duke
parents:
diff changeset
96 public boolean setUnion(BitMap other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 Assert.that(size() == other.size(), "must have same size");
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100 boolean changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 for (int index = 0; index < sizeInWords(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 int temp = data[index] | other.data[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
103 changed = changed || (temp != data[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
104 data[index] = temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 /** Sets this bitmap to the logical intersection of it and the
a61af66fc99e Initial load
duke
parents:
diff changeset
110 argument. Both bitmaps must be the same size. */
a61af66fc99e Initial load
duke
parents:
diff changeset
111 public void setIntersection(BitMap other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 Assert.that(size() == other.size(), "must have same size");
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115 for (int index = 0; index < sizeInWords(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 data[index] = data[index] & (other.data[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 /** Sets this bitmap to the contents of the argument. Both bitmaps
a61af66fc99e Initial load
duke
parents:
diff changeset
121 must be the same size. */
a61af66fc99e Initial load
duke
parents:
diff changeset
122 public void setFrom(BitMap other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 Assert.that(size() == other.size(), "must have same size");
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 for (int index = 0; index < sizeInWords(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 data[index] = other.data[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 /** Sets this bitmap to the logical difference between it and the
a61af66fc99e Initial load
duke
parents:
diff changeset
132 argument; that is, any bits that are set in the argument are
a61af66fc99e Initial load
duke
parents:
diff changeset
133 cleared in this bitmap. Both bitmaps must be the same size.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Returns true if a change was caused in this bitmap. */
a61af66fc99e Initial load
duke
parents:
diff changeset
135 public boolean setDifference(BitMap other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 Assert.that(size() == other.size(), "must have same size");
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 boolean changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 for (int index = 0; index < sizeInWords(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 int temp = data[index] & ~(other.data[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
142 changed = changed || (temp != data[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 data[index] = temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 /** Both bitmaps must be the same size. */
a61af66fc99e Initial load
duke
parents:
diff changeset
149 public boolean isSame(BitMap other) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 Assert.that(size() == other.size(), "must have same size");
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153 for (int index = 0; index < sizeInWords(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 if (data[index] != (other.data[index])) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 public int getNextOneOffset(int l_offset, int r_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if (l_offset == r_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 return l_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 int index = indexFor(l_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
165 int r_index = indexFor(r_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 int res_offset = l_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 int pos = bitInWord(res_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 int res = data[index] >> pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 if (res != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // find the position of the 1-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
173 for (; (res & 1) == 0; res_offset++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 res = res >> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 return res_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // skip over all word length 0-bit runs
a61af66fc99e Initial load
duke
parents:
diff changeset
179 for (index++; index < r_index; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 res = data[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (res != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // found a 1, return the offset
a61af66fc99e Initial load
duke
parents:
diff changeset
183 for (res_offset = index * bitsPerWord; (res & 1) == 0; res_offset++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 res = res >> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 return res_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return r_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
194 //
a61af66fc99e Initial load
duke
parents:
diff changeset
195 private int size; // in bits
a61af66fc99e Initial load
duke
parents:
diff changeset
196 private int[] data;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 private static final int bitsPerWord = 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 private static final int bytesPerWord = 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 private int sizeInWords() {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return (size() + bitsPerWord - 1) / bitsPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 private int indexFor(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 return offset / bitsPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 private int wordFor(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 return data[offset / bitsPerWord];
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 private int bitInWord(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return offset & (bitsPerWord - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }