Mercurial > hg > truffle
annotate src/share/vm/classfile/verificationType.hpp @ 3762:5c0a3c1858b1
7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675.
Reviewed-by: brutisso
author | ysr |
---|---|
date | Thu, 02 Jun 2011 10:23:36 -0700 |
parents | 1d1603768966 |
children | 4ee06e614636 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2303
diff
changeset
|
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP |
26 #define SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP | |
27 | |
28 #include "classfile/systemDictionary.hpp" | |
29 #include "memory/allocation.hpp" | |
30 #include "oops/instanceKlass.hpp" | |
31 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
32 #include "oops/symbol.hpp" |
1972 | 33 #include "runtime/handles.hpp" |
34 #include "runtime/signature.hpp" | |
35 | |
0 | 36 enum { |
37 // As specifed in the JVM spec | |
38 ITEM_Top = 0, | |
39 ITEM_Integer = 1, | |
40 ITEM_Float = 2, | |
41 ITEM_Double = 3, | |
42 ITEM_Long = 4, | |
43 ITEM_Null = 5, | |
44 ITEM_UninitializedThis = 6, | |
45 ITEM_Object = 7, | |
46 ITEM_Uninitialized = 8, | |
47 ITEM_Bogus = (uint)-1 | |
48 }; | |
49 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
50 class ClassVerifier; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
51 |
0 | 52 class VerificationType VALUE_OBJ_CLASS_SPEC { |
53 private: | |
54 // Least significant bits of _handle are always 0, so we use these as | |
55 // the indicator that the _handle is valid. Otherwise, the _data field | |
56 // contains encoded data (as specified below). Should the VM change | |
57 // and the lower bits on oops aren't 0, the assert in the constructor | |
58 // will catch this and we'll have to add a descriminator tag to this | |
59 // structure. | |
60 union { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
61 Symbol* _sym; |
0 | 62 uintptr_t _data; |
63 } _u; | |
64 | |
65 enum { | |
66 // These rest are not found in classfiles, but used by the verifier | |
67 ITEM_Boolean = 9, ITEM_Byte, ITEM_Short, ITEM_Char, | |
68 ITEM_Long_2nd, ITEM_Double_2nd | |
69 }; | |
70 | |
71 // Enum for the _data field | |
72 enum { | |
73 // Bottom two bits determine if the type is a reference, primitive, | |
74 // uninitialized or a query-type. | |
75 TypeMask = 0x00000003, | |
76 | |
77 // Topmost types encoding | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
78 Reference = 0x0, // _sym contains the name |
0 | 79 Primitive = 0x1, // see below for primitive list |
80 Uninitialized = 0x2, // 0x00ffff00 contains bci | |
81 TypeQuery = 0x3, // Meta-types used for category testing | |
82 | |
83 // Utility flags | |
84 ReferenceFlag = 0x00, // For reference query types | |
85 Category1Flag = 0x01, // One-word values | |
86 Category2Flag = 0x02, // First word of a two-word value | |
87 Category2_2ndFlag = 0x04, // Second word of a two-word value | |
88 | |
89 // special reference values | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
90 Null = 0x00000000, // A reference with a 0 sym is null |
0 | 91 |
92 // Primitives categories (the second byte determines the category) | |
93 Category1 = (Category1Flag << 1 * BitsPerByte) | Primitive, | |
94 Category2 = (Category2Flag << 1 * BitsPerByte) | Primitive, | |
95 Category2_2nd = (Category2_2ndFlag << 1 * BitsPerByte) | Primitive, | |
96 | |
97 // Primitive values (type descriminator stored in most-signifcant bytes) | |
98 Bogus = (ITEM_Bogus << 2 * BitsPerByte) | Category1, | |
99 Boolean = (ITEM_Boolean << 2 * BitsPerByte) | Category1, | |
100 Byte = (ITEM_Byte << 2 * BitsPerByte) | Category1, | |
101 Short = (ITEM_Short << 2 * BitsPerByte) | Category1, | |
102 Char = (ITEM_Char << 2 * BitsPerByte) | Category1, | |
103 Integer = (ITEM_Integer << 2 * BitsPerByte) | Category1, | |
104 Float = (ITEM_Float << 2 * BitsPerByte) | Category1, | |
105 Long = (ITEM_Long << 2 * BitsPerByte) | Category2, | |
106 Double = (ITEM_Double << 2 * BitsPerByte) | Category2, | |
107 Long_2nd = (ITEM_Long_2nd << 2 * BitsPerByte) | Category2_2nd, | |
108 Double_2nd = (ITEM_Double_2nd << 2 * BitsPerByte) | Category2_2nd, | |
109 | |
110 // Used by Uninitialized (second and third bytes hold the bci) | |
111 BciMask = 0xffff << 1 * BitsPerByte, | |
112 BciForThis = ((u2)-1), // A bci of -1 is an Unintialized-This | |
113 | |
114 // Query values | |
115 ReferenceQuery = (ReferenceFlag << 1 * BitsPerByte) | TypeQuery, | |
116 Category1Query = (Category1Flag << 1 * BitsPerByte) | TypeQuery, | |
117 Category2Query = (Category2Flag << 1 * BitsPerByte) | TypeQuery, | |
118 Category2_2ndQuery = (Category2_2ndFlag << 1 * BitsPerByte) | TypeQuery | |
119 }; | |
120 | |
121 VerificationType(uintptr_t raw_data) { | |
122 _u._data = raw_data; | |
123 } | |
124 | |
125 public: | |
126 | |
127 VerificationType() { *this = bogus_type(); } | |
128 | |
129 // Create verification types | |
130 static VerificationType bogus_type() { return VerificationType(Bogus); } | |
2303
c1a6154012c8
7020118: Alter frame assignability to allow for exception handler coverage of invokespecial <init>
kamg
parents:
2177
diff
changeset
|
131 static VerificationType top_type() { return bogus_type(); } // alias |
0 | 132 static VerificationType null_type() { return VerificationType(Null); } |
133 static VerificationType integer_type() { return VerificationType(Integer); } | |
134 static VerificationType float_type() { return VerificationType(Float); } | |
135 static VerificationType long_type() { return VerificationType(Long); } | |
136 static VerificationType long2_type() { return VerificationType(Long_2nd); } | |
137 static VerificationType double_type() { return VerificationType(Double); } | |
138 static VerificationType boolean_type() { return VerificationType(Boolean); } | |
139 static VerificationType byte_type() { return VerificationType(Byte); } | |
140 static VerificationType char_type() { return VerificationType(Char); } | |
141 static VerificationType short_type() { return VerificationType(Short); } | |
142 static VerificationType double2_type() | |
143 { return VerificationType(Double_2nd); } | |
144 | |
145 // "check" types are used for queries. A "check" type is not assignable | |
146 // to anything, but the specified types are assignable to a "check". For | |
147 // example, any category1 primitive is assignable to category1_check and | |
148 // any reference is assignable to reference_check. | |
149 static VerificationType reference_check() | |
150 { return VerificationType(ReferenceQuery); } | |
151 static VerificationType category1_check() | |
152 { return VerificationType(Category1Query); } | |
153 static VerificationType category2_check() | |
154 { return VerificationType(Category2Query); } | |
155 static VerificationType category2_2nd_check() | |
156 { return VerificationType(Category2_2ndQuery); } | |
157 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
158 // For reference types, store the actual Symbol |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
159 static VerificationType reference_type(Symbol* sh) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
160 assert(((uintptr_t)sh & 0x3) == 0, "Oops must be aligned"); |
0 | 161 // If the above assert fails in the future because oop* isn't aligned, |
162 // then this type encoding system will have to change to have a tag value | |
163 // to descriminate between oops and primitives. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
164 return VerificationType((uintptr_t)sh); |
0 | 165 } |
166 static VerificationType uninitialized_type(u2 bci) | |
167 { return VerificationType(bci << 1 * BitsPerByte | Uninitialized); } | |
168 static VerificationType uninitialized_this_type() | |
169 { return uninitialized_type(BciForThis); } | |
170 | |
171 // Create based on u1 read from classfile | |
172 static VerificationType from_tag(u1 tag); | |
173 | |
174 bool is_bogus() const { return (_u._data == Bogus); } | |
175 bool is_null() const { return (_u._data == Null); } | |
176 bool is_boolean() const { return (_u._data == Boolean); } | |
177 bool is_byte() const { return (_u._data == Byte); } | |
178 bool is_char() const { return (_u._data == Char); } | |
179 bool is_short() const { return (_u._data == Short); } | |
180 bool is_integer() const { return (_u._data == Integer); } | |
181 bool is_long() const { return (_u._data == Long); } | |
182 bool is_float() const { return (_u._data == Float); } | |
183 bool is_double() const { return (_u._data == Double); } | |
184 bool is_long2() const { return (_u._data == Long_2nd); } | |
185 bool is_double2() const { return (_u._data == Double_2nd); } | |
186 bool is_reference() const { return ((_u._data & TypeMask) == Reference); } | |
187 bool is_category1() const { | |
188 // This should return true for all one-word types, which are category1 | |
189 // primitives, and references (including uninitialized refs). Though | |
190 // the 'query' types should technically return 'false' here, if we | |
191 // allow this to return true, we can perform the test using only | |
192 // 2 operations rather than 8 (3 masks, 3 compares and 2 logical 'ands'). | |
193 // Since noone should call this on a query type anyway, this is ok. | |
194 assert(!is_check(), "Must not be a check type (wrong value returned)"); | |
195 return ((_u._data & Category1) != Primitive); | |
196 // should only return false if it's a primitive, and the category1 flag | |
197 // is not set. | |
198 } | |
199 bool is_category2() const { return ((_u._data & Category2) == Category2); } | |
200 bool is_category2_2nd() const { | |
201 return ((_u._data & Category2_2nd) == Category2_2nd); | |
202 } | |
203 bool is_reference_check() const { return _u._data == ReferenceQuery; } | |
204 bool is_category1_check() const { return _u._data == Category1Query; } | |
205 bool is_category2_check() const { return _u._data == Category2Query; } | |
206 bool is_category2_2nd_check() const { return _u._data == Category2_2ndQuery; } | |
207 bool is_check() const { return (_u._data & TypeQuery) == TypeQuery; } | |
208 | |
209 bool is_x_array(char sig) const { | |
210 return is_null() || (is_array() && (name()->byte_at(1) == sig)); | |
211 } | |
212 bool is_int_array() const { return is_x_array('I'); } | |
213 bool is_byte_array() const { return is_x_array('B'); } | |
214 bool is_bool_array() const { return is_x_array('Z'); } | |
215 bool is_char_array() const { return is_x_array('C'); } | |
216 bool is_short_array() const { return is_x_array('S'); } | |
217 bool is_long_array() const { return is_x_array('J'); } | |
218 bool is_float_array() const { return is_x_array('F'); } | |
219 bool is_double_array() const { return is_x_array('D'); } | |
220 bool is_object_array() const { return is_x_array('L'); } | |
221 bool is_array_array() const { return is_x_array('['); } | |
222 bool is_reference_array() const | |
223 { return is_object_array() || is_array_array(); } | |
224 bool is_object() const | |
225 { return (is_reference() && !is_null() && name()->utf8_length() >= 1 && | |
226 name()->byte_at(0) != '['); } | |
227 bool is_array() const | |
228 { return (is_reference() && !is_null() && name()->utf8_length() >= 2 && | |
229 name()->byte_at(0) == '['); } | |
230 bool is_uninitialized() const | |
231 { return ((_u._data & Uninitialized) == Uninitialized); } | |
232 bool is_uninitialized_this() const | |
233 { return is_uninitialized() && bci() == BciForThis; } | |
234 | |
235 VerificationType to_category2_2nd() const { | |
236 assert(is_category2(), "Must be a double word"); | |
237 return VerificationType(is_long() ? Long_2nd : Double_2nd); | |
238 } | |
239 | |
240 u2 bci() const { | |
241 assert(is_uninitialized(), "Must be uninitialized type"); | |
242 return ((_u._data & BciMask) >> 1 * BitsPerByte); | |
243 } | |
244 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
245 Symbol* name() const { |
0 | 246 assert(is_reference() && !is_null(), "Must be a non-null reference"); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
247 return _u._sym; |
0 | 248 } |
249 | |
250 bool equals(const VerificationType& t) const { | |
251 return (_u._data == t._u._data || | |
252 (is_reference() && t.is_reference() && !is_null() && !t.is_null() && | |
253 name() == t.name())); | |
254 } | |
255 | |
256 bool operator ==(const VerificationType& t) const { | |
257 return equals(t); | |
258 } | |
259 | |
260 bool operator !=(const VerificationType& t) const { | |
261 return !equals(t); | |
262 } | |
263 | |
264 // The whole point of this type system - check to see if one type | |
265 // is assignable to another. Returns true if one can assign 'from' to | |
266 // this. | |
267 bool is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
268 const VerificationType& from, ClassVerifier* context, TRAPS) const { |
0 | 269 if (equals(from) || is_bogus()) { |
270 return true; | |
271 } else { | |
272 switch(_u._data) { | |
273 case Category1Query: | |
274 return from.is_category1(); | |
275 case Category2Query: | |
276 return from.is_category2(); | |
277 case Category2_2ndQuery: | |
278 return from.is_category2_2nd(); | |
279 case ReferenceQuery: | |
280 return from.is_reference() || from.is_uninitialized(); | |
281 case Boolean: | |
282 case Byte: | |
283 case Char: | |
284 case Short: | |
285 // An int can be assigned to boolean, byte, char or short values. | |
286 return from.is_integer(); | |
287 default: | |
288 if (is_reference() && from.is_reference()) { | |
289 return is_reference_assignable_from(from, context, CHECK_false); | |
290 } else { | |
291 return false; | |
292 } | |
293 } | |
294 } | |
295 } | |
296 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
297 VerificationType get_component(ClassVerifier* context, TRAPS) const; |
0 | 298 |
299 int dimensions() const { | |
300 assert(is_array(), "Must be an array"); | |
301 int index = 0; | |
302 while (name()->byte_at(index++) == '['); | |
303 return index; | |
304 } | |
305 | |
306 void print_on(outputStream* st) const PRODUCT_RETURN; | |
307 | |
308 private: | |
309 | |
310 bool is_reference_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
311 const VerificationType&, ClassVerifier*, TRAPS) const; |
0 | 312 }; |
1972 | 313 |
314 #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP |