Mercurial > hg > truffle
comparison agent/src/share/classes/sun/jvm/hotspot/oops/CellTypeState.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 2001 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 package sun.jvm.hotspot.oops; | |
26 | |
27 import java.io.*; | |
28 import sun.jvm.hotspot.utilities.*; | |
29 | |
30 /** Auxiliary class for GenerateOopMap */ | |
31 public class CellTypeState { | |
32 private int _state; | |
33 | |
34 // Masks for separating the BITS and INFO portions of a | |
35 // CellTypeState | |
36 private static final int info_mask = Bits.rightNBits(28); | |
37 private static final int bits_mask = ~info_mask; | |
38 | |
39 // These constant are used for manipulating the BITS portion of a | |
40 // CellTypeState | |
41 private static final int uninit_bit = Bits.nthBit(31); | |
42 private static final int ref_bit = Bits.nthBit(30); | |
43 private static final int val_bit = Bits.nthBit(29); | |
44 private static final int addr_bit = Bits.nthBit(28); | |
45 private static final int live_bits_mask = bits_mask & ~uninit_bit; | |
46 | |
47 // These constants are used for manipulating the INFO portion of a | |
48 // CellTypeState | |
49 private static final int top_info_bit = Bits.nthBit(27); | |
50 private static final int not_bottom_info_bit = Bits.nthBit(26); | |
51 private static final int info_data_mask = Bits.rightNBits(26); | |
52 private static final int info_conflict = info_mask; | |
53 | |
54 // Within the INFO data, these values are used to distinguish | |
55 // different kinds of references. | |
56 // 0 if this reference is locked as a monitor | |
57 private static final int ref_not_lock_bit = Bits.nthBit(25); | |
58 // 1 if this reference is a "slot" reference | |
59 private static final int ref_slot_bit = Bits.nthBit(24); | |
60 // 0 if it is a "line" reference. | |
61 private static final int ref_data_mask = Bits.rightNBits(24); | |
62 | |
63 // These values are used to initialize commonly used CellTypeState | |
64 // constants. | |
65 private static final int bottom_value = 0; | |
66 private static final int uninit_value = uninit_bit | info_conflict; | |
67 private static final int ref_value = ref_bit; | |
68 private static final int ref_conflict = ref_bit | info_conflict; | |
69 private static final int val_value = val_bit | info_conflict; | |
70 private static final int addr_value = addr_bit; | |
71 private static final int addr_conflict = addr_bit | info_conflict; | |
72 | |
73 private CellTypeState() {} | |
74 | |
75 private CellTypeState(int state) { | |
76 _state = state; | |
77 } | |
78 | |
79 public CellTypeState copy() { | |
80 return new CellTypeState(_state); | |
81 } | |
82 | |
83 public static CellTypeState makeAny(int state) { | |
84 CellTypeState s = new CellTypeState(state); | |
85 if (Assert.ASSERTS_ENABLED) { | |
86 Assert.that(s.isValidState(), "check to see if CellTypeState is valid"); | |
87 } | |
88 return s; | |
89 } | |
90 | |
91 public static CellTypeState makeBottom() { | |
92 return makeAny(0); | |
93 } | |
94 | |
95 public static CellTypeState makeTop() { | |
96 return makeAny(Bits.AllBits); | |
97 } | |
98 | |
99 public static CellTypeState makeAddr(int bci) { | |
100 if (Assert.ASSERTS_ENABLED) { | |
101 Assert.that((bci >= 0) && (bci < info_data_mask), | |
102 "check to see if ret addr is valid"); | |
103 } | |
104 return makeAny(addr_bit | not_bottom_info_bit | (bci & info_data_mask)); | |
105 } | |
106 | |
107 public static CellTypeState makeSlotRef(int slot_num) { | |
108 if (Assert.ASSERTS_ENABLED) { | |
109 Assert.that(slot_num >= 0 && slot_num < ref_data_mask, "slot out of range"); | |
110 } | |
111 return makeAny(ref_bit | not_bottom_info_bit | ref_not_lock_bit | ref_slot_bit | | |
112 (slot_num & ref_data_mask)); | |
113 } | |
114 | |
115 public static CellTypeState makeLineRef(int bci) { | |
116 if (Assert.ASSERTS_ENABLED) { | |
117 Assert.that(bci >= 0 && bci < ref_data_mask, "line out of range"); | |
118 } | |
119 return makeAny(ref_bit | not_bottom_info_bit | ref_not_lock_bit | | |
120 (bci & ref_data_mask)); | |
121 } | |
122 | |
123 public static CellTypeState makeLockRef(int bci) { | |
124 if (Assert.ASSERTS_ENABLED) { | |
125 Assert.that(bci >= 0 && bci < ref_data_mask, "line out of range"); | |
126 } | |
127 return makeAny(ref_bit | not_bottom_info_bit | (bci & ref_data_mask)); | |
128 } | |
129 | |
130 // Query methods: | |
131 public boolean isBottom() { return _state == 0; } | |
132 public boolean isLive() { return ((_state & live_bits_mask) != 0); } | |
133 public boolean isValidState() { | |
134 // Uninitialized and value cells must contain no data in their info field: | |
135 if ((canBeUninit() || canBeValue()) && !isInfoTop()) { | |
136 return false; | |
137 } | |
138 // The top bit is only set when all info bits are set: | |
139 if (isInfoTop() && ((_state & info_mask) != info_mask)) { | |
140 return false; | |
141 } | |
142 // The not_bottom_bit must be set when any other info bit is set: | |
143 if (isInfoBottom() && ((_state & info_mask) != 0)) { | |
144 return false; | |
145 } | |
146 return true; | |
147 } | |
148 | |
149 public boolean isAddress() { return ((_state & bits_mask) == addr_bit); } | |
150 public boolean isReference() { return ((_state & bits_mask) == ref_bit); } | |
151 public boolean isValue() { return ((_state & bits_mask) == val_bit); } | |
152 public boolean isUninit() { return ((_state & bits_mask) == uninit_bit); } | |
153 | |
154 public boolean canBeAddress() { return ((_state & addr_bit) != 0); } | |
155 public boolean canBeReference() { return ((_state & ref_bit) != 0); } | |
156 public boolean canBeValue() { return ((_state & val_bit) != 0); } | |
157 public boolean canBeUninit() { return ((_state & uninit_bit) != 0); } | |
158 | |
159 public boolean isInfoBottom() { return ((_state & not_bottom_info_bit) == 0); } | |
160 public boolean isInfoTop() { return ((_state & top_info_bit) != 0); } | |
161 public int getInfo() { | |
162 if (Assert.ASSERTS_ENABLED) { | |
163 Assert.that((!isInfoTop() && !isInfoBottom()), | |
164 "check to make sure top/bottom info is not used"); | |
165 } | |
166 return (_state & info_data_mask); | |
167 } | |
168 | |
169 public int getMonitorSource() { | |
170 if (Assert.ASSERTS_ENABLED) { | |
171 Assert.that(isLockReference(), "must be lock"); | |
172 } | |
173 return getInfo(); | |
174 } | |
175 | |
176 public boolean isGoodAddress() { return isAddress() && !isInfoTop(); } | |
177 public boolean isLockReference() { | |
178 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == ref_bit); | |
179 } | |
180 public boolean isNonlockReference() { | |
181 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == (ref_bit | ref_not_lock_bit)); | |
182 } | |
183 | |
184 public boolean equal(CellTypeState a) { return _state == a._state; } | |
185 public boolean equalKind(CellTypeState a) { | |
186 return (_state & bits_mask) == (a._state & bits_mask); | |
187 } | |
188 | |
189 public char toChar() { | |
190 if (canBeReference()) { | |
191 if (canBeValue() || canBeAddress()) | |
192 return '#'; // Conflict that needs to be rewritten | |
193 else | |
194 return 'r'; | |
195 } else if (canBeValue()) | |
196 return 'v'; | |
197 else if (canBeAddress()) | |
198 return 'p'; | |
199 else if (canBeUninit()) | |
200 return ' '; | |
201 else | |
202 return '@'; | |
203 } | |
204 | |
205 // Set | |
206 public void set(CellTypeState cts) { | |
207 _state = cts._state; | |
208 } | |
209 | |
210 // Merge | |
211 public CellTypeState merge (CellTypeState cts, int slot) { | |
212 CellTypeState result = new CellTypeState(); | |
213 | |
214 if (Assert.ASSERTS_ENABLED) { | |
215 Assert.that(!isBottom() && !cts.isBottom(), | |
216 "merge of bottom values is handled elsewhere"); | |
217 } | |
218 | |
219 result._state = _state | cts._state; | |
220 | |
221 // If the top bit is set, we don't need to do any more work. | |
222 if (!result.isInfoTop()) { | |
223 Assert.that((result.canBeAddress() || result.canBeReference()), | |
224 "only addresses and references have non-top info"); | |
225 | |
226 if (!equal(cts)) { | |
227 // The two values being merged are different. Raise to top. | |
228 if (result.isReference()) { | |
229 result = CellTypeState.makeSlotRef(slot); | |
230 } else { | |
231 result._state |= info_conflict; | |
232 } | |
233 } | |
234 } | |
235 if (Assert.ASSERTS_ENABLED) { | |
236 Assert.that(result.isValidState(), "checking that CTS merge maintains legal state"); | |
237 } | |
238 | |
239 return result; | |
240 } | |
241 | |
242 // Debugging output | |
243 public void print(PrintStream tty) { | |
244 if (canBeAddress()) { | |
245 tty.print("(p"); | |
246 } else { | |
247 tty.print("( "); | |
248 } | |
249 if (canBeReference()) { | |
250 tty.print("r"); | |
251 } else { | |
252 tty.print(" "); | |
253 } | |
254 if (canBeValue()) { | |
255 tty.print("v"); | |
256 } else { | |
257 tty.print(" "); | |
258 } | |
259 if (canBeUninit()) { | |
260 tty.print("u|"); | |
261 } else { | |
262 tty.print(" |"); | |
263 } | |
264 if (isInfoTop()) { | |
265 tty.print("Top)"); | |
266 } else if (isInfoBottom()) { | |
267 tty.print("Bot)"); | |
268 } else { | |
269 if (isReference()) { | |
270 int info = getInfo(); | |
271 int data = info & ~(ref_not_lock_bit | ref_slot_bit); | |
272 if ((info & ref_not_lock_bit) != 0) { | |
273 // Not a monitor lock reference. | |
274 if ((info & ref_slot_bit) != 0) { | |
275 // slot | |
276 tty.print("slot" + data + ")"); | |
277 } else { | |
278 // line | |
279 tty.print("line" + data + ")"); | |
280 } | |
281 } else { | |
282 // lock | |
283 tty.print("lock" + data + ")"); | |
284 } | |
285 } else { | |
286 tty.print("" + getInfo() + ")"); | |
287 } | |
288 } | |
289 } | |
290 | |
291 // Default values of common values | |
292 public static CellTypeState bottom = CellTypeState.makeBottom(); | |
293 public static CellTypeState uninit = CellTypeState.makeAny(uninit_value); | |
294 public static CellTypeState ref = CellTypeState.makeAny(ref_conflict); | |
295 public static CellTypeState value = CellTypeState.makeAny(val_value); | |
296 public static CellTypeState refUninit = CellTypeState.makeAny(ref_conflict | uninit_value); | |
297 public static CellTypeState top = CellTypeState.makeTop(); | |
298 public static CellTypeState addr = CellTypeState.makeAny(addr_conflict); | |
299 } |