Mercurial > hg > truffle
annotate src/share/vm/classfile/verifier.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:
2177
diff
changeset
|
2 * Copyright (c) 1998, 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:
973
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
973
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:
973
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CLASSFILE_VERIFIER_HPP |
26 #define SHARE_VM_CLASSFILE_VERIFIER_HPP | |
27 | |
28 #include "classfile/verificationType.hpp" | |
29 #include "memory/gcLocker.hpp" | |
30 #include "oops/klass.hpp" | |
31 #include "oops/methodOop.hpp" | |
32 #include "runtime/handles.hpp" | |
33 #include "utilities/exceptions.hpp" | |
34 | |
0 | 35 // The verifier class |
36 class Verifier : AllStatic { | |
37 public: | |
1602 | 38 enum { |
39 STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50, | |
40 INVOKEDYNAMIC_MAJOR_VERSION = 51 | |
41 }; | |
0 | 42 typedef enum { ThrowException, NoException } Mode; |
43 | |
44 /** | |
45 * Verify the bytecodes for a class. If 'throw_exception' is true | |
46 * then the appropriate VerifyError or ClassFormatError will be thrown. | |
47 * Otherwise, no exception is thrown and the return indicates the | |
48 * error. | |
49 */ | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
0
diff
changeset
|
50 static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS); |
0 | 51 |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
0
diff
changeset
|
52 // Return false if the class is loaded by the bootstrap loader, |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
0
diff
changeset
|
53 // or if defineClass was called requesting skipping verification |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
0
diff
changeset
|
54 // -Xverify:all/none override this value |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
0
diff
changeset
|
55 static bool should_verify_for(oop class_loader, bool should_verify_class); |
0 | 56 |
57 // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2. | |
58 static bool relax_verify_for(oop class_loader); | |
59 | |
60 private: | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
0
diff
changeset
|
61 static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
62 static Symbol* inference_verify( |
0 | 63 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS); |
64 }; | |
65 | |
66 class RawBytecodeStream; | |
67 class StackMapFrame; | |
68 class StackMapTable; | |
69 | |
70 // Summary of verifier's memory usage: | |
71 // StackMapTable is stack allocated. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
72 // StackMapFrame are resource allocated. There is only one ResourceMark |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
73 // for each class verification, which is created at the top level. |
0 | 74 // There is one mutable StackMapFrame (current_frame) which is updated |
75 // by abstract bytecode interpretation. frame_in_exception_handler() returns | |
76 // a frame that has a mutable one-item stack (ready for pushing the | |
77 // catch type exception object). All the other StackMapFrame's | |
78 // are immutable (including their locals and stack arrays) after | |
79 // their constructions. | |
80 // locals/stack arrays in StackMapFrame are resource allocated. | |
81 // locals/stack arrays can be shared between StackMapFrame's, except | |
82 // the mutable StackMapFrame (current_frame). | |
83 | |
84 // These macros are used similarly to CHECK macros but also check | |
85 // the status of the verifier and return if that has an error. | |
86 #define CHECK_VERIFY(verifier) \ | |
87 CHECK); if ((verifier)->has_error()) return; (0 | |
88 #define CHECK_VERIFY_(verifier, result) \ | |
89 CHECK_(result)); if ((verifier)->has_error()) return (result); (0 | |
90 | |
91 // A new instance of this class is created for each class being verified | |
92 class ClassVerifier : public StackObj { | |
93 private: | |
94 Thread* _thread; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
95 Symbol* _exception_type; |
0 | 96 char* _message; |
97 size_t _message_buffer_len; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
98 GrowableArray<Symbol*>* _symbols; // keep a list of symbols created |
0 | 99 |
100 void verify_method(methodHandle method, TRAPS); | |
101 char* generate_code_data(methodHandle m, u4 code_length, TRAPS); | |
102 void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS); | |
103 void verify_local_variable_table(u4 code_length, char* code_data, TRAPS); | |
104 | |
105 VerificationType cp_ref_index_to_type( | |
106 int index, constantPoolHandle cp, TRAPS) { | |
107 return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD); | |
108 } | |
109 | |
110 bool is_protected_access( | |
111 instanceKlassHandle this_class, klassOop target_class, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
112 Symbol* field_name, Symbol* field_sig, bool is_method); |
0 | 113 |
114 void verify_cp_index(constantPoolHandle cp, int index, TRAPS); | |
115 void verify_cp_type( | |
116 int index, constantPoolHandle cp, unsigned int types, TRAPS); | |
117 void verify_cp_class_type(int index, constantPoolHandle cp, TRAPS); | |
118 | |
119 u2 verify_stackmap_table( | |
120 u2 stackmap_index, u2 bci, StackMapFrame* current_frame, | |
121 StackMapTable* stackmap_table, bool no_control_flow, TRAPS); | |
122 | |
123 void verify_exception_handler_targets( | |
124 u2 bci, bool this_uninit, StackMapFrame* current_frame, | |
125 StackMapTable* stackmap_table, TRAPS); | |
126 | |
127 void verify_ldc( | |
128 int opcode, u2 index, StackMapFrame *current_frame, | |
129 constantPoolHandle cp, u2 bci, TRAPS); | |
130 | |
131 void verify_switch( | |
132 RawBytecodeStream* bcs, u4 code_length, char* code_data, | |
133 StackMapFrame* current_frame, StackMapTable* stackmap_table, TRAPS); | |
134 | |
135 void verify_field_instructions( | |
136 RawBytecodeStream* bcs, StackMapFrame* current_frame, | |
137 constantPoolHandle cp, TRAPS); | |
138 | |
139 void verify_invoke_init( | |
140 RawBytecodeStream* bcs, VerificationType ref_class_type, | |
141 StackMapFrame* current_frame, u4 code_length, bool* this_uninit, | |
142 constantPoolHandle cp, TRAPS); | |
143 | |
144 void verify_invoke_instructions( | |
145 RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, | |
146 bool* this_uninit, VerificationType return_type, | |
147 constantPoolHandle cp, TRAPS); | |
148 | |
149 VerificationType get_newarray_type(u2 index, u2 bci, TRAPS); | |
150 void verify_anewarray( | |
151 u2 index, constantPoolHandle cp, StackMapFrame* current_frame, TRAPS); | |
152 void verify_return_value( | |
153 VerificationType return_type, VerificationType type, u2 offset, TRAPS); | |
154 | |
155 void verify_iload (u2 index, StackMapFrame* current_frame, TRAPS); | |
156 void verify_lload (u2 index, StackMapFrame* current_frame, TRAPS); | |
157 void verify_fload (u2 index, StackMapFrame* current_frame, TRAPS); | |
158 void verify_dload (u2 index, StackMapFrame* current_frame, TRAPS); | |
159 void verify_aload (u2 index, StackMapFrame* current_frame, TRAPS); | |
160 void verify_istore(u2 index, StackMapFrame* current_frame, TRAPS); | |
161 void verify_lstore(u2 index, StackMapFrame* current_frame, TRAPS); | |
162 void verify_fstore(u2 index, StackMapFrame* current_frame, TRAPS); | |
163 void verify_dstore(u2 index, StackMapFrame* current_frame, TRAPS); | |
164 void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS); | |
165 void verify_iinc (u2 index, StackMapFrame* current_frame, TRAPS); | |
166 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
167 bool name_in_supers(Symbol* ref_name, instanceKlassHandle current); |
0 | 168 |
1955
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1602
diff
changeset
|
169 VerificationType object_type() const; |
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1602
diff
changeset
|
170 |
0 | 171 instanceKlassHandle _klass; // the class being verified |
172 methodHandle _method; // current method being verified | |
173 VerificationType _this_type; // the verification type of the current class | |
174 | |
1570 | 175 // Some recursive calls from the verifier to the name resolver |
176 // can cause the current class to be re-verified and rewritten. | |
177 // If this happens, the original verification should not continue, | |
178 // because constant pool indexes will have changed. | |
179 // The rewriter is preceded by the verifier. If the verifier throws | |
180 // an error, rewriting is prevented. Also, rewriting always precedes | |
181 // bytecode execution or compilation. Thus, is_rewritten implies | |
182 // that a class has been verified and prepared for execution. | |
183 bool was_recursively_verified() { return _klass->is_rewritten(); } | |
184 | |
0 | 185 public: |
186 enum { | |
187 BYTECODE_OFFSET = 1, | |
188 NEW_OFFSET = 2 | |
189 }; | |
190 | |
191 // constructor | |
192 ClassVerifier(instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS); | |
193 | |
194 // destructor | |
195 ~ClassVerifier(); | |
196 | |
197 Thread* thread() { return _thread; } | |
198 methodHandle method() { return _method; } | |
199 instanceKlassHandle current_class() const { return _klass; } | |
200 VerificationType current_type() const { return _this_type; } | |
201 | |
202 // Verifies the class. If a verify or class file format error occurs, | |
203 // the '_exception_name' symbols will set to the exception name and | |
204 // the message_buffer will be filled in with the exception message. | |
205 void verify_class(TRAPS); | |
206 | |
207 // Return status modes | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
208 Symbol* result() const { return _exception_type; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
209 bool has_error() const { return result() != NULL; } |
0 | 210 |
211 // Called when verify or class format errors are encountered. | |
212 // May throw an exception based upon the mode. | |
213 void verify_error(u2 offset, const char* fmt, ...); | |
214 void verify_error(const char* fmt, ...); | |
215 void class_format_error(const char* fmt, ...); | |
216 void format_error_message(const char* fmt, int offset, va_list args); | |
217 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
218 klassOop load_class(Symbol* name, TRAPS); |
0 | 219 |
220 int change_sig_to_verificationType( | |
221 SignatureStream* sig_type, VerificationType* inference_type, TRAPS); | |
222 | |
223 VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
224 return VerificationType::reference_type(cp->klass_name_at(index)); |
0 | 225 } |
226 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
227 // Keep a list of temporary symbols created during verification because |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
228 // their reference counts need to be decrememented when the verifier object |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
229 // goes out of scope. Since these symbols escape the scope in which they're |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
230 // created, we can't use a TempNewSymbol. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
231 Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
232 Symbol* create_temporary_symbol(const char *s, int length, TRAPS); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
233 |
0 | 234 static bool _verify_verbose; // for debugging |
235 }; | |
236 | |
237 inline int ClassVerifier::change_sig_to_verificationType( | |
238 SignatureStream* sig_type, VerificationType* inference_type, TRAPS) { | |
239 BasicType bt = sig_type->type(); | |
240 switch (bt) { | |
241 case T_OBJECT: | |
242 case T_ARRAY: | |
243 { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
244 Symbol* name = sig_type->as_symbol(CHECK_0); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
245 // Create another symbol to save as signature stream unreferences |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
246 // this symbol. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
247 Symbol* name_copy = |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
248 create_temporary_symbol(name, 0, name->utf8_length(), CHECK_0); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
249 assert(name_copy == name, "symbols don't match"); |
0 | 250 *inference_type = |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
251 VerificationType::reference_type(name_copy); |
0 | 252 return 1; |
253 } | |
254 case T_LONG: | |
255 *inference_type = VerificationType::long_type(); | |
256 *++inference_type = VerificationType::long2_type(); | |
257 return 2; | |
258 case T_DOUBLE: | |
259 *inference_type = VerificationType::double_type(); | |
260 *++inference_type = VerificationType::double2_type(); | |
261 return 2; | |
262 case T_INT: | |
263 case T_BOOLEAN: | |
264 case T_BYTE: | |
265 case T_CHAR: | |
266 case T_SHORT: | |
267 *inference_type = VerificationType::integer_type(); | |
268 return 1; | |
269 case T_FLOAT: | |
270 *inference_type = VerificationType::float_type(); | |
271 return 1; | |
272 default: | |
273 ShouldNotReachHere(); | |
274 return 1; | |
275 } | |
276 } | |
1972 | 277 |
278 #endif // SHARE_VM_CLASSFILE_VERIFIER_HPP |