Mercurial > hg > truffle
annotate src/share/vm/classfile/verifier.cpp @ 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 | ed69575596ac |
children | e17b61ba7bb3 d558e01a72c0 |
rev | line source |
---|---|
0 | 1 /* |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2192
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:
1142
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1142
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:
1142
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classFileStream.hpp" | |
27 #include "classfile/javaClasses.hpp" | |
28 #include "classfile/stackMapTable.hpp" | |
29 #include "classfile/systemDictionary.hpp" | |
30 #include "classfile/verifier.hpp" | |
31 #include "classfile/vmSymbols.hpp" | |
32 #include "interpreter/bytecodeStream.hpp" | |
33 #include "memory/oopFactory.hpp" | |
34 #include "memory/resourceArea.hpp" | |
35 #include "oops/instanceKlass.hpp" | |
36 #include "oops/oop.inline.hpp" | |
37 #include "oops/typeArrayOop.hpp" | |
38 #include "prims/jvm.h" | |
39 #include "runtime/fieldDescriptor.hpp" | |
40 #include "runtime/handles.inline.hpp" | |
41 #include "runtime/interfaceSupport.hpp" | |
42 #include "runtime/javaCalls.hpp" | |
43 #include "runtime/orderAccess.hpp" | |
44 #include "runtime/os.hpp" | |
45 #ifdef TARGET_ARCH_x86 | |
46 # include "bytes_x86.hpp" | |
47 #endif | |
48 #ifdef TARGET_ARCH_sparc | |
49 # include "bytes_sparc.hpp" | |
50 #endif | |
51 #ifdef TARGET_ARCH_zero | |
52 # include "bytes_zero.hpp" | |
53 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
54 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
55 # include "bytes_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
56 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
57 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
58 # include "bytes_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
59 #endif |
0 | 60 |
1560
e40a3601bc1f
6911922: JVM must throw VerifyError for jsr or jsr_w opcodes in class file v.51+
kamg
parents:
1142
diff
changeset
|
61 #define NOFAILOVER_MAJOR_VERSION 51 |
e40a3601bc1f
6911922: JVM must throw VerifyError for jsr or jsr_w opcodes in class file v.51+
kamg
parents:
1142
diff
changeset
|
62 |
0 | 63 // Access to external entry for VerifyClassCodes - old byte code verifier |
64 | |
65 extern "C" { | |
66 typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint); | |
67 typedef jboolean (*verify_byte_codes_fn_new_t)(JNIEnv *, jclass, char *, jint, jint); | |
68 } | |
69 | |
70 static void* volatile _verify_byte_codes_fn = NULL; | |
71 | |
72 static volatile jint _is_new_verify_byte_codes_fn = (jint) true; | |
73 | |
74 static void* verify_byte_codes_fn() { | |
75 if (_verify_byte_codes_fn == NULL) { | |
76 void *lib_handle = os::native_java_library(); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
77 void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion"); |
0 | 78 OrderAccess::release_store_ptr(&_verify_byte_codes_fn, func); |
79 if (func == NULL) { | |
80 OrderAccess::release_store(&_is_new_verify_byte_codes_fn, false); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
81 func = os::dll_lookup(lib_handle, "VerifyClassCodes"); |
0 | 82 OrderAccess::release_store_ptr(&_verify_byte_codes_fn, func); |
83 } | |
84 } | |
85 return (void*)_verify_byte_codes_fn; | |
86 } | |
87 | |
88 | |
89 // Methods in Verifier | |
90 | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
91 bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) { |
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
92 return (class_loader == NULL || !should_verify_class) ? |
0 | 93 BytecodeVerificationLocal : BytecodeVerificationRemote; |
94 } | |
95 | |
96 bool Verifier::relax_verify_for(oop loader) { | |
97 bool trusted = java_lang_ClassLoader::is_trusted_loader(loader); | |
98 bool need_verify = | |
99 // verifyAll | |
100 (BytecodeVerificationLocal && BytecodeVerificationRemote) || | |
101 // verifyRemote | |
102 (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted); | |
103 return !need_verify; | |
104 } | |
105 | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
106 bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
107 HandleMark hm; |
0 | 108 ResourceMark rm(THREAD); |
109 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
110 Symbol* exception_name = NULL; |
0 | 111 const size_t message_buffer_len = klass->name()->utf8_length() + 1024; |
112 char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); | |
113 | |
114 const char* klassName = klass->external_name(); | |
115 | |
116 // If the class should be verified, first see if we can use the split | |
117 // verifier. If not, or if verification fails and FailOverToOldVerifier | |
118 // is set, then call the inference verifier. | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
119 if (is_eligible_for_verification(klass, should_verify_class)) { |
0 | 120 if (TraceClassInitialization) { |
121 tty->print_cr("Start class verification for: %s", klassName); | |
122 } | |
123 if (UseSplitVerifier && | |
124 klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { | |
125 ClassVerifier split_verifier( | |
126 klass, message_buffer, message_buffer_len, THREAD); | |
127 split_verifier.verify_class(THREAD); | |
128 exception_name = split_verifier.result(); | |
1560
e40a3601bc1f
6911922: JVM must throw VerifyError for jsr or jsr_w opcodes in class file v.51+
kamg
parents:
1142
diff
changeset
|
129 if (klass->major_version() < NOFAILOVER_MAJOR_VERSION && |
e40a3601bc1f
6911922: JVM must throw VerifyError for jsr or jsr_w opcodes in class file v.51+
kamg
parents:
1142
diff
changeset
|
130 FailOverToOldVerifier && !HAS_PENDING_EXCEPTION && |
0 | 131 (exception_name == vmSymbols::java_lang_VerifyError() || |
132 exception_name == vmSymbols::java_lang_ClassFormatError())) { | |
133 if (TraceClassInitialization) { | |
134 tty->print_cr( | |
135 "Fail over class verification to old verifier for: %s", klassName); | |
136 } | |
137 exception_name = inference_verify( | |
138 klass, message_buffer, message_buffer_len, THREAD); | |
139 } | |
140 } else { | |
141 exception_name = inference_verify( | |
142 klass, message_buffer, message_buffer_len, THREAD); | |
143 } | |
144 | |
145 if (TraceClassInitialization) { | |
146 if (HAS_PENDING_EXCEPTION) { | |
147 tty->print("Verification for %s has", klassName); | |
148 tty->print_cr(" exception pending %s ", | |
149 instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
150 } else if (exception_name != NULL) { |
0 | 151 tty->print_cr("Verification for %s failed", klassName); |
152 } | |
153 tty->print_cr("End class verification for: %s", klassName); | |
154 } | |
155 } | |
156 | |
157 if (HAS_PENDING_EXCEPTION) { | |
158 return false; // use the existing exception | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
159 } else if (exception_name == NULL) { |
0 | 160 return true; // verifcation succeeded |
161 } else { // VerifyError or ClassFormatError to be created and thrown | |
162 ResourceMark rm(THREAD); | |
163 instanceKlassHandle kls = | |
164 SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false); | |
165 while (!kls.is_null()) { | |
166 if (kls == klass) { | |
167 // If the class being verified is the exception we're creating | |
168 // or one of it's superclasses, we're in trouble and are going | |
169 // to infinitely recurse when we try to initialize the exception. | |
170 // So bail out here by throwing the preallocated VM error. | |
171 THROW_OOP_(Universe::virtual_machine_error_instance(), false); | |
172 } | |
173 kls = kls->super(); | |
174 } | |
175 message_buffer[message_buffer_len - 1] = '\0'; // just to be sure | |
176 THROW_MSG_(exception_name, message_buffer, false); | |
177 } | |
178 } | |
179 | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
180 bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
181 Symbol* name = klass->name(); |
1142 | 182 klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); |
0 | 183 |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
184 return (should_verify_for(klass->class_loader(), should_verify_class) && |
0 | 185 // return if the class is a bootstrapping class |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
844
diff
changeset
|
186 // or defineClass specified not to verify by default (flags override passed arg) |
0 | 187 // We need to skip the following four for bootstraping |
188 name != vmSymbols::java_lang_Object() && | |
189 name != vmSymbols::java_lang_Class() && | |
190 name != vmSymbols::java_lang_String() && | |
191 name != vmSymbols::java_lang_Throwable() && | |
192 | |
193 // Can not verify the bytecodes for shared classes because they have | |
194 // already been rewritten to contain constant pool cache indices, | |
195 // which the verifier can't understand. | |
196 // Shared classes shouldn't have stackmaps either. | |
197 !klass()->is_shared() && | |
198 | |
199 // As of the fix for 4486457 we disable verification for all of the | |
200 // dynamically-generated bytecodes associated with the 1.4 | |
201 // reflection implementation, not just those associated with | |
202 // sun/reflect/SerializationConstructorAccessor. | |
203 // NOTE: this is called too early in the bootstrapping process to be | |
204 // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. | |
205 (refl_magic_klass == NULL || | |
206 !klass->is_subtype_of(refl_magic_klass) || | |
207 VerifyReflectionBytecodes) | |
208 ); | |
209 } | |
210 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
211 Symbol* Verifier::inference_verify( |
0 | 212 instanceKlassHandle klass, char* message, size_t message_len, TRAPS) { |
213 JavaThread* thread = (JavaThread*)THREAD; | |
214 JNIEnv *env = thread->jni_environment(); | |
215 | |
216 void* verify_func = verify_byte_codes_fn(); | |
217 | |
218 if (verify_func == NULL) { | |
219 jio_snprintf(message, message_len, "Could not link verifier"); | |
220 return vmSymbols::java_lang_VerifyError(); | |
221 } | |
222 | |
223 ResourceMark rm(THREAD); | |
224 if (ClassVerifier::_verify_verbose) { | |
225 tty->print_cr("Verifying class %s with old format", klass->external_name()); | |
226 } | |
227 | |
228 jclass cls = (jclass) JNIHandles::make_local(env, klass->java_mirror()); | |
229 jint result; | |
230 | |
231 { | |
232 HandleMark hm(thread); | |
233 ThreadToNativeFromVM ttn(thread); | |
234 // ThreadToNativeFromVM takes care of changing thread_state, so safepoint | |
235 // code knows that we have left the VM | |
236 | |
237 if (_is_new_verify_byte_codes_fn) { | |
238 verify_byte_codes_fn_new_t func = | |
239 CAST_TO_FN_PTR(verify_byte_codes_fn_new_t, verify_func); | |
240 result = (*func)(env, cls, message, (int)message_len, | |
241 klass->major_version()); | |
242 } else { | |
243 verify_byte_codes_fn_t func = | |
244 CAST_TO_FN_PTR(verify_byte_codes_fn_t, verify_func); | |
245 result = (*func)(env, cls, message, (int)message_len); | |
246 } | |
247 } | |
248 | |
249 JNIHandles::destroy_local(cls); | |
250 | |
251 // These numbers are chosen so that VerifyClassCodes interface doesn't need | |
252 // to be changed (still return jboolean (unsigned char)), and result is | |
253 // 1 when verification is passed. | |
254 if (result == 0) { | |
255 return vmSymbols::java_lang_VerifyError(); | |
256 } else if (result == 1) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
257 return NULL; // verified. |
0 | 258 } else if (result == 2) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
259 THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL); |
0 | 260 } else if (result == 3) { |
261 return vmSymbols::java_lang_ClassFormatError(); | |
262 } else { | |
263 ShouldNotReachHere(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
264 return NULL; |
0 | 265 } |
266 } | |
267 | |
268 // Methods in ClassVerifier | |
269 | |
270 bool ClassVerifier::_verify_verbose = false; | |
271 | |
272 ClassVerifier::ClassVerifier( | |
273 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
274 : _thread(THREAD), _exception_type(NULL), _message(msg), |
0 | 275 _message_buffer_len(msg_len), _klass(klass) { |
276 _this_type = VerificationType::reference_type(klass->name()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
277 // Create list to hold symbols in reference area. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
278 _symbols = new GrowableArray<Symbol*>(100, 0, NULL); |
0 | 279 } |
280 | |
281 ClassVerifier::~ClassVerifier() { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
282 // Decrement the reference count for any symbols created. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
283 for (int i = 0; i < _symbols->length(); i++) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
284 Symbol* s = _symbols->at(i); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
285 s->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
286 } |
0 | 287 } |
288 | |
1955
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
289 VerificationType ClassVerifier::object_type() const { |
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
290 return VerificationType::reference_type(vmSymbols::java_lang_Object()); |
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
291 } |
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
292 |
0 | 293 void ClassVerifier::verify_class(TRAPS) { |
294 if (_verify_verbose) { | |
295 tty->print_cr("Verifying class %s with new format", | |
296 _klass->external_name()); | |
297 } | |
298 | |
299 objArrayHandle methods(THREAD, _klass->methods()); | |
300 int num_methods = methods->length(); | |
301 | |
302 for (int index = 0; index < num_methods; index++) { | |
1570 | 303 // Check for recursive re-verification before each method. |
304 if (was_recursively_verified()) return; | |
305 | |
0 | 306 methodOop m = (methodOop)methods->obj_at(index); |
307 if (m->is_native() || m->is_abstract()) { | |
308 // If m is native or abstract, skip it. It is checked in class file | |
309 // parser that methods do not override a final method. | |
310 continue; | |
311 } | |
312 verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this)); | |
313 } | |
1570 | 314 |
315 if (_verify_verbose || TraceClassInitialization) { | |
316 if (was_recursively_verified()) | |
317 tty->print_cr("Recursive verification detected for: %s", | |
318 _klass->external_name()); | |
319 } | |
0 | 320 } |
321 | |
322 void ClassVerifier::verify_method(methodHandle m, TRAPS) { | |
323 _method = m; // initialize _method | |
324 if (_verify_verbose) { | |
325 tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); | |
326 } | |
327 | |
328 const char* bad_type_msg = "Bad type on operand stack in %s"; | |
329 | |
330 int32_t max_stack = m->max_stack(); | |
331 int32_t max_locals = m->max_locals(); | |
332 constantPoolHandle cp(THREAD, m->constants()); | |
333 | |
334 if (!SignatureVerifier::is_valid_method_signature(m->signature())) { | |
335 class_format_error("Invalid method signature"); | |
336 return; | |
337 } | |
338 | |
339 // Initial stack map frame: offset is 0, stack is initially empty. | |
340 StackMapFrame current_frame(max_locals, max_stack, this); | |
341 // Set initial locals | |
342 VerificationType return_type = current_frame.set_locals_from_arg( | |
343 m, current_type(), CHECK_VERIFY(this)); | |
344 | |
345 int32_t stackmap_index = 0; // index to the stackmap array | |
346 | |
347 u4 code_length = m->code_size(); | |
348 | |
349 // Scan the bytecode and map each instruction's start offset to a number. | |
350 char* code_data = generate_code_data(m, code_length, CHECK_VERIFY(this)); | |
351 | |
352 int ex_min = code_length; | |
353 int ex_max = -1; | |
354 // Look through each item on the exception table. Each of the fields must refer | |
355 // to a legal instruction. | |
356 verify_exception_handler_table( | |
357 code_length, code_data, ex_min, ex_max, CHECK_VERIFY(this)); | |
358 | |
359 // Look through each entry on the local variable table and make sure | |
360 // its range of code array offsets is valid. (4169817) | |
361 if (m->has_localvariable_table()) { | |
362 verify_local_variable_table(code_length, code_data, CHECK_VERIFY(this)); | |
363 } | |
364 | |
365 typeArrayHandle stackmap_data(THREAD, m->stackmap_data()); | |
366 StackMapStream stream(stackmap_data); | |
367 StackMapReader reader(this, &stream, code_data, code_length, THREAD); | |
368 StackMapTable stackmap_table(&reader, ¤t_frame, max_locals, max_stack, | |
369 code_data, code_length, CHECK_VERIFY(this)); | |
370 | |
371 if (_verify_verbose) { | |
372 stackmap_table.print(); | |
373 } | |
374 | |
375 RawBytecodeStream bcs(m); | |
376 | |
377 // Scan the byte code linearly from the start to the end | |
378 bool no_control_flow = false; // Set to true when there is no direct control | |
379 // flow from current instruction to the next | |
380 // instruction in sequence | |
381 Bytecodes::Code opcode; | |
382 while (!bcs.is_last_bytecode()) { | |
1570 | 383 // Check for recursive re-verification before each bytecode. |
384 if (was_recursively_verified()) return; | |
385 | |
0 | 386 opcode = bcs.raw_next(); |
387 u2 bci = bcs.bci(); | |
388 | |
389 // Set current frame's offset to bci | |
390 current_frame.set_offset(bci); | |
391 | |
392 // Make sure every offset in stackmap table point to the beginning to | |
393 // an instruction. Match current_frame to stackmap_table entry with | |
394 // the same offset if exists. | |
395 stackmap_index = verify_stackmap_table( | |
396 stackmap_index, bci, ¤t_frame, &stackmap_table, | |
397 no_control_flow, CHECK_VERIFY(this)); | |
398 | |
399 bool this_uninit = false; // Set to true when invokespecial <init> initialized 'this' | |
400 | |
401 // Merge with the next instruction | |
402 { | |
403 u2 index; | |
404 int target; | |
405 VerificationType type, type2; | |
406 VerificationType atype; | |
407 | |
408 #ifndef PRODUCT | |
409 if (_verify_verbose) { | |
410 current_frame.print(); | |
411 tty->print_cr("offset = %d, opcode = %s", bci, Bytecodes::name(opcode)); | |
412 } | |
413 #endif | |
414 | |
415 // Make sure wide instruction is in correct format | |
416 if (bcs.is_wide()) { | |
417 if (opcode != Bytecodes::_iinc && opcode != Bytecodes::_iload && | |
418 opcode != Bytecodes::_aload && opcode != Bytecodes::_lload && | |
419 opcode != Bytecodes::_istore && opcode != Bytecodes::_astore && | |
420 opcode != Bytecodes::_lstore && opcode != Bytecodes::_fload && | |
421 opcode != Bytecodes::_dload && opcode != Bytecodes::_fstore && | |
422 opcode != Bytecodes::_dstore) { | |
423 verify_error(bci, "Bad wide instruction"); | |
424 return; | |
425 } | |
426 } | |
427 | |
428 switch (opcode) { | |
429 case Bytecodes::_nop : | |
430 no_control_flow = false; break; | |
431 case Bytecodes::_aconst_null : | |
432 current_frame.push_stack( | |
433 VerificationType::null_type(), CHECK_VERIFY(this)); | |
434 no_control_flow = false; break; | |
435 case Bytecodes::_iconst_m1 : | |
436 case Bytecodes::_iconst_0 : | |
437 case Bytecodes::_iconst_1 : | |
438 case Bytecodes::_iconst_2 : | |
439 case Bytecodes::_iconst_3 : | |
440 case Bytecodes::_iconst_4 : | |
441 case Bytecodes::_iconst_5 : | |
442 current_frame.push_stack( | |
443 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
444 no_control_flow = false; break; | |
445 case Bytecodes::_lconst_0 : | |
446 case Bytecodes::_lconst_1 : | |
447 current_frame.push_stack_2( | |
448 VerificationType::long_type(), | |
449 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
450 no_control_flow = false; break; | |
451 case Bytecodes::_fconst_0 : | |
452 case Bytecodes::_fconst_1 : | |
453 case Bytecodes::_fconst_2 : | |
454 current_frame.push_stack( | |
455 VerificationType::float_type(), CHECK_VERIFY(this)); | |
456 no_control_flow = false; break; | |
457 case Bytecodes::_dconst_0 : | |
458 case Bytecodes::_dconst_1 : | |
459 current_frame.push_stack_2( | |
460 VerificationType::double_type(), | |
461 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
462 no_control_flow = false; break; | |
463 case Bytecodes::_sipush : | |
464 case Bytecodes::_bipush : | |
465 current_frame.push_stack( | |
466 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
467 no_control_flow = false; break; | |
468 case Bytecodes::_ldc : | |
469 verify_ldc( | |
1565 | 470 opcode, bcs.get_index_u1(), ¤t_frame, |
0 | 471 cp, bci, CHECK_VERIFY(this)); |
472 no_control_flow = false; break; | |
473 case Bytecodes::_ldc_w : | |
474 case Bytecodes::_ldc2_w : | |
475 verify_ldc( | |
1565 | 476 opcode, bcs.get_index_u2(), ¤t_frame, |
0 | 477 cp, bci, CHECK_VERIFY(this)); |
478 no_control_flow = false; break; | |
479 case Bytecodes::_iload : | |
480 verify_iload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
481 no_control_flow = false; break; | |
482 case Bytecodes::_iload_0 : | |
483 case Bytecodes::_iload_1 : | |
484 case Bytecodes::_iload_2 : | |
485 case Bytecodes::_iload_3 : | |
486 index = opcode - Bytecodes::_iload_0; | |
487 verify_iload(index, ¤t_frame, CHECK_VERIFY(this)); | |
488 no_control_flow = false; break; | |
489 case Bytecodes::_lload : | |
490 verify_lload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
491 no_control_flow = false; break; | |
492 case Bytecodes::_lload_0 : | |
493 case Bytecodes::_lload_1 : | |
494 case Bytecodes::_lload_2 : | |
495 case Bytecodes::_lload_3 : | |
496 index = opcode - Bytecodes::_lload_0; | |
497 verify_lload(index, ¤t_frame, CHECK_VERIFY(this)); | |
498 no_control_flow = false; break; | |
499 case Bytecodes::_fload : | |
500 verify_fload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
501 no_control_flow = false; break; | |
502 case Bytecodes::_fload_0 : | |
503 case Bytecodes::_fload_1 : | |
504 case Bytecodes::_fload_2 : | |
505 case Bytecodes::_fload_3 : | |
506 index = opcode - Bytecodes::_fload_0; | |
507 verify_fload(index, ¤t_frame, CHECK_VERIFY(this)); | |
508 no_control_flow = false; break; | |
509 case Bytecodes::_dload : | |
510 verify_dload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
511 no_control_flow = false; break; | |
512 case Bytecodes::_dload_0 : | |
513 case Bytecodes::_dload_1 : | |
514 case Bytecodes::_dload_2 : | |
515 case Bytecodes::_dload_3 : | |
516 index = opcode - Bytecodes::_dload_0; | |
517 verify_dload(index, ¤t_frame, CHECK_VERIFY(this)); | |
518 no_control_flow = false; break; | |
519 case Bytecodes::_aload : | |
520 verify_aload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
521 no_control_flow = false; break; | |
522 case Bytecodes::_aload_0 : | |
523 case Bytecodes::_aload_1 : | |
524 case Bytecodes::_aload_2 : | |
525 case Bytecodes::_aload_3 : | |
526 index = opcode - Bytecodes::_aload_0; | |
527 verify_aload(index, ¤t_frame, CHECK_VERIFY(this)); | |
528 no_control_flow = false; break; | |
529 case Bytecodes::_iaload : | |
530 type = current_frame.pop_stack( | |
531 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
532 atype = current_frame.pop_stack( | |
533 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
534 if (!atype.is_int_array()) { | |
535 verify_error(bci, bad_type_msg, "iaload"); | |
536 return; | |
537 } | |
538 current_frame.push_stack( | |
539 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
540 no_control_flow = false; break; | |
541 case Bytecodes::_baload : | |
542 type = current_frame.pop_stack( | |
543 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
544 atype = current_frame.pop_stack( | |
545 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
546 if (!atype.is_bool_array() && !atype.is_byte_array()) { | |
547 verify_error(bci, bad_type_msg, "baload"); | |
548 return; | |
549 } | |
550 current_frame.push_stack( | |
551 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
552 no_control_flow = false; break; | |
553 case Bytecodes::_caload : | |
554 type = current_frame.pop_stack( | |
555 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
556 atype = current_frame.pop_stack( | |
557 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
558 if (!atype.is_char_array()) { | |
559 verify_error(bci, bad_type_msg, "caload"); | |
560 return; | |
561 } | |
562 current_frame.push_stack( | |
563 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
564 no_control_flow = false; break; | |
565 case Bytecodes::_saload : | |
566 type = current_frame.pop_stack( | |
567 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
568 atype = current_frame.pop_stack( | |
569 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
570 if (!atype.is_short_array()) { | |
571 verify_error(bci, bad_type_msg, "saload"); | |
572 return; | |
573 } | |
574 current_frame.push_stack( | |
575 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
576 no_control_flow = false; break; | |
577 case Bytecodes::_laload : | |
578 type = current_frame.pop_stack( | |
579 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
580 atype = current_frame.pop_stack( | |
581 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
582 if (!atype.is_long_array()) { | |
583 verify_error(bci, bad_type_msg, "laload"); | |
584 return; | |
585 } | |
586 current_frame.push_stack_2( | |
587 VerificationType::long_type(), | |
588 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
589 no_control_flow = false; break; | |
590 case Bytecodes::_faload : | |
591 type = current_frame.pop_stack( | |
592 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
593 atype = current_frame.pop_stack( | |
594 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
595 if (!atype.is_float_array()) { | |
596 verify_error(bci, bad_type_msg, "faload"); | |
597 return; | |
598 } | |
599 current_frame.push_stack( | |
600 VerificationType::float_type(), CHECK_VERIFY(this)); | |
601 no_control_flow = false; break; | |
602 case Bytecodes::_daload : | |
603 type = current_frame.pop_stack( | |
604 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
605 atype = current_frame.pop_stack( | |
606 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
607 if (!atype.is_double_array()) { | |
608 verify_error(bci, bad_type_msg, "daload"); | |
609 return; | |
610 } | |
611 current_frame.push_stack_2( | |
612 VerificationType::double_type(), | |
613 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
614 no_control_flow = false; break; | |
615 case Bytecodes::_aaload : { | |
616 type = current_frame.pop_stack( | |
617 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
618 atype = current_frame.pop_stack( | |
619 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
620 if (!atype.is_reference_array()) { | |
621 verify_error(bci, bad_type_msg, "aaload"); | |
622 return; | |
623 } | |
624 if (atype.is_null()) { | |
625 current_frame.push_stack( | |
626 VerificationType::null_type(), CHECK_VERIFY(this)); | |
627 } else { | |
628 VerificationType component = | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
629 atype.get_component(this, CHECK_VERIFY(this)); |
0 | 630 current_frame.push_stack(component, CHECK_VERIFY(this)); |
631 } | |
632 no_control_flow = false; break; | |
633 } | |
634 case Bytecodes::_istore : | |
635 verify_istore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
636 no_control_flow = false; break; | |
637 case Bytecodes::_istore_0 : | |
638 case Bytecodes::_istore_1 : | |
639 case Bytecodes::_istore_2 : | |
640 case Bytecodes::_istore_3 : | |
641 index = opcode - Bytecodes::_istore_0; | |
642 verify_istore(index, ¤t_frame, CHECK_VERIFY(this)); | |
643 no_control_flow = false; break; | |
644 case Bytecodes::_lstore : | |
645 verify_lstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
646 no_control_flow = false; break; | |
647 case Bytecodes::_lstore_0 : | |
648 case Bytecodes::_lstore_1 : | |
649 case Bytecodes::_lstore_2 : | |
650 case Bytecodes::_lstore_3 : | |
651 index = opcode - Bytecodes::_lstore_0; | |
652 verify_lstore(index, ¤t_frame, CHECK_VERIFY(this)); | |
653 no_control_flow = false; break; | |
654 case Bytecodes::_fstore : | |
655 verify_fstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
656 no_control_flow = false; break; | |
657 case Bytecodes::_fstore_0 : | |
658 case Bytecodes::_fstore_1 : | |
659 case Bytecodes::_fstore_2 : | |
660 case Bytecodes::_fstore_3 : | |
661 index = opcode - Bytecodes::_fstore_0; | |
662 verify_fstore(index, ¤t_frame, CHECK_VERIFY(this)); | |
663 no_control_flow = false; break; | |
664 case Bytecodes::_dstore : | |
665 verify_dstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
666 no_control_flow = false; break; | |
667 case Bytecodes::_dstore_0 : | |
668 case Bytecodes::_dstore_1 : | |
669 case Bytecodes::_dstore_2 : | |
670 case Bytecodes::_dstore_3 : | |
671 index = opcode - Bytecodes::_dstore_0; | |
672 verify_dstore(index, ¤t_frame, CHECK_VERIFY(this)); | |
673 no_control_flow = false; break; | |
674 case Bytecodes::_astore : | |
675 verify_astore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
676 no_control_flow = false; break; | |
677 case Bytecodes::_astore_0 : | |
678 case Bytecodes::_astore_1 : | |
679 case Bytecodes::_astore_2 : | |
680 case Bytecodes::_astore_3 : | |
681 index = opcode - Bytecodes::_astore_0; | |
682 verify_astore(index, ¤t_frame, CHECK_VERIFY(this)); | |
683 no_control_flow = false; break; | |
684 case Bytecodes::_iastore : | |
685 type = current_frame.pop_stack( | |
686 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
687 type2 = current_frame.pop_stack( | |
688 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
689 atype = current_frame.pop_stack( | |
690 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
691 if (!atype.is_int_array()) { | |
692 verify_error(bci, bad_type_msg, "iastore"); | |
693 return; | |
694 } | |
695 no_control_flow = false; break; | |
696 case Bytecodes::_bastore : | |
697 type = current_frame.pop_stack( | |
698 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
699 type2 = current_frame.pop_stack( | |
700 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
701 atype = current_frame.pop_stack( | |
702 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
703 if (!atype.is_bool_array() && !atype.is_byte_array()) { | |
704 verify_error(bci, bad_type_msg, "bastore"); | |
705 return; | |
706 } | |
707 no_control_flow = false; break; | |
708 case Bytecodes::_castore : | |
709 current_frame.pop_stack( | |
710 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
711 current_frame.pop_stack( | |
712 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
713 atype = current_frame.pop_stack( | |
714 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
715 if (!atype.is_char_array()) { | |
716 verify_error(bci, bad_type_msg, "castore"); | |
717 return; | |
718 } | |
719 no_control_flow = false; break; | |
720 case Bytecodes::_sastore : | |
721 current_frame.pop_stack( | |
722 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
723 current_frame.pop_stack( | |
724 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
725 atype = current_frame.pop_stack( | |
726 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
727 if (!atype.is_short_array()) { | |
728 verify_error(bci, bad_type_msg, "sastore"); | |
729 return; | |
730 } | |
731 no_control_flow = false; break; | |
732 case Bytecodes::_lastore : | |
733 current_frame.pop_stack_2( | |
734 VerificationType::long2_type(), | |
735 VerificationType::long_type(), CHECK_VERIFY(this)); | |
736 current_frame.pop_stack( | |
737 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
738 atype = current_frame.pop_stack( | |
739 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
740 if (!atype.is_long_array()) { | |
741 verify_error(bci, bad_type_msg, "lastore"); | |
742 return; | |
743 } | |
744 no_control_flow = false; break; | |
745 case Bytecodes::_fastore : | |
746 current_frame.pop_stack( | |
747 VerificationType::float_type(), CHECK_VERIFY(this)); | |
748 current_frame.pop_stack | |
749 (VerificationType::integer_type(), CHECK_VERIFY(this)); | |
750 atype = current_frame.pop_stack( | |
751 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
752 if (!atype.is_float_array()) { | |
753 verify_error(bci, bad_type_msg, "fastore"); | |
754 return; | |
755 } | |
756 no_control_flow = false; break; | |
757 case Bytecodes::_dastore : | |
758 current_frame.pop_stack_2( | |
759 VerificationType::double2_type(), | |
760 VerificationType::double_type(), CHECK_VERIFY(this)); | |
761 current_frame.pop_stack( | |
762 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
763 atype = current_frame.pop_stack( | |
764 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
765 if (!atype.is_double_array()) { | |
766 verify_error(bci, bad_type_msg, "dastore"); | |
767 return; | |
768 } | |
769 no_control_flow = false; break; | |
770 case Bytecodes::_aastore : | |
1955
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
771 type = current_frame.pop_stack(object_type(), CHECK_VERIFY(this)); |
0 | 772 type2 = current_frame.pop_stack( |
773 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
774 atype = current_frame.pop_stack( | |
775 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
776 // more type-checking is done at runtime | |
777 if (!atype.is_reference_array()) { | |
778 verify_error(bci, bad_type_msg, "aastore"); | |
779 return; | |
780 } | |
781 // 4938384: relaxed constraint in JVMS 3nd edition. | |
782 no_control_flow = false; break; | |
783 case Bytecodes::_pop : | |
784 current_frame.pop_stack( | |
785 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
786 no_control_flow = false; break; | |
787 case Bytecodes::_pop2 : | |
788 type = current_frame.pop_stack(CHECK_VERIFY(this)); | |
789 if (type.is_category1()) { | |
790 current_frame.pop_stack( | |
791 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
792 } else if (type.is_category2_2nd()) { | |
793 current_frame.pop_stack( | |
794 VerificationType::category2_check(), CHECK_VERIFY(this)); | |
795 } else { | |
796 verify_error(bci, bad_type_msg, "pop2"); | |
797 return; | |
798 } | |
799 no_control_flow = false; break; | |
800 case Bytecodes::_dup : | |
801 type = current_frame.pop_stack( | |
802 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
803 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
804 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
805 no_control_flow = false; break; | |
806 case Bytecodes::_dup_x1 : | |
807 type = current_frame.pop_stack( | |
808 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
809 type2 = current_frame.pop_stack( | |
810 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
811 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
812 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
813 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
814 no_control_flow = false; break; | |
815 case Bytecodes::_dup_x2 : | |
816 { | |
817 VerificationType type3; | |
818 type = current_frame.pop_stack( | |
819 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
820 type2 = current_frame.pop_stack(CHECK_VERIFY(this)); | |
821 if (type2.is_category1()) { | |
822 type3 = current_frame.pop_stack( | |
823 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
824 } else if (type2.is_category2_2nd()) { | |
825 type3 = current_frame.pop_stack( | |
826 VerificationType::category2_check(), CHECK_VERIFY(this)); | |
827 } else { | |
828 verify_error(bci, bad_type_msg, "dup_x2"); | |
829 return; | |
830 } | |
831 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
832 current_frame.push_stack(type3, CHECK_VERIFY(this)); | |
833 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
834 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
835 no_control_flow = false; break; | |
836 } | |
837 case Bytecodes::_dup2 : | |
838 type = current_frame.pop_stack(CHECK_VERIFY(this)); | |
839 if (type.is_category1()) { | |
840 type2 = current_frame.pop_stack( | |
841 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
842 } else if (type.is_category2_2nd()) { | |
843 type2 = current_frame.pop_stack( | |
844 VerificationType::category2_check(), CHECK_VERIFY(this)); | |
845 } else { | |
846 verify_error(bci, bad_type_msg, "dup2"); | |
847 return; | |
848 } | |
849 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
850 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
851 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
852 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
853 no_control_flow = false; break; | |
854 case Bytecodes::_dup2_x1 : | |
855 { | |
856 VerificationType type3; | |
857 type = current_frame.pop_stack(CHECK_VERIFY(this)); | |
858 if (type.is_category1()) { | |
859 type2 = current_frame.pop_stack( | |
860 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
861 } else if(type.is_category2_2nd()) { | |
862 type2 = current_frame.pop_stack | |
863 (VerificationType::category2_check(), CHECK_VERIFY(this)); | |
864 } else { | |
865 verify_error(bci, bad_type_msg, "dup2_x1"); | |
866 return; | |
867 } | |
868 type3 = current_frame.pop_stack( | |
869 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
870 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
871 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
872 current_frame.push_stack(type3, CHECK_VERIFY(this)); | |
873 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
874 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
875 no_control_flow = false; break; | |
876 } | |
877 case Bytecodes::_dup2_x2 : | |
878 { | |
879 VerificationType type3, type4; | |
880 type = current_frame.pop_stack(CHECK_VERIFY(this)); | |
881 if (type.is_category1()) { | |
882 type2 = current_frame.pop_stack( | |
883 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
884 } else if (type.is_category2_2nd()) { | |
885 type2 = current_frame.pop_stack( | |
886 VerificationType::category2_check(), CHECK_VERIFY(this)); | |
887 } else { | |
888 verify_error(bci, bad_type_msg, "dup2_x2"); | |
889 return; | |
890 } | |
891 type3 = current_frame.pop_stack(CHECK_VERIFY(this)); | |
892 if (type3.is_category1()) { | |
893 type4 = current_frame.pop_stack( | |
894 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
895 } else if (type3.is_category2_2nd()) { | |
896 type4 = current_frame.pop_stack( | |
897 VerificationType::category2_check(), CHECK_VERIFY(this)); | |
898 } else { | |
899 verify_error(bci, bad_type_msg, "dup2_x2"); | |
900 return; | |
901 } | |
902 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
903 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
904 current_frame.push_stack(type4, CHECK_VERIFY(this)); | |
905 current_frame.push_stack(type3, CHECK_VERIFY(this)); | |
906 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
907 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
908 no_control_flow = false; break; | |
909 } | |
910 case Bytecodes::_swap : | |
911 type = current_frame.pop_stack( | |
912 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
913 type2 = current_frame.pop_stack( | |
914 VerificationType::category1_check(), CHECK_VERIFY(this)); | |
915 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
916 current_frame.push_stack(type2, CHECK_VERIFY(this)); | |
917 no_control_flow = false; break; | |
918 case Bytecodes::_iadd : | |
919 case Bytecodes::_isub : | |
920 case Bytecodes::_imul : | |
921 case Bytecodes::_idiv : | |
922 case Bytecodes::_irem : | |
923 case Bytecodes::_ishl : | |
924 case Bytecodes::_ishr : | |
925 case Bytecodes::_iushr : | |
926 case Bytecodes::_ior : | |
927 case Bytecodes::_ixor : | |
928 case Bytecodes::_iand : | |
929 current_frame.pop_stack( | |
930 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
931 // fall through | |
932 case Bytecodes::_ineg : | |
933 current_frame.pop_stack( | |
934 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
935 current_frame.push_stack( | |
936 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
937 no_control_flow = false; break; | |
938 case Bytecodes::_ladd : | |
939 case Bytecodes::_lsub : | |
940 case Bytecodes::_lmul : | |
941 case Bytecodes::_ldiv : | |
942 case Bytecodes::_lrem : | |
943 case Bytecodes::_land : | |
944 case Bytecodes::_lor : | |
945 case Bytecodes::_lxor : | |
946 current_frame.pop_stack_2( | |
947 VerificationType::long2_type(), | |
948 VerificationType::long_type(), CHECK_VERIFY(this)); | |
949 // fall through | |
950 case Bytecodes::_lneg : | |
951 current_frame.pop_stack_2( | |
952 VerificationType::long2_type(), | |
953 VerificationType::long_type(), CHECK_VERIFY(this)); | |
954 current_frame.push_stack_2( | |
955 VerificationType::long_type(), | |
956 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
957 no_control_flow = false; break; | |
958 case Bytecodes::_lshl : | |
959 case Bytecodes::_lshr : | |
960 case Bytecodes::_lushr : | |
961 current_frame.pop_stack( | |
962 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
963 current_frame.pop_stack_2( | |
964 VerificationType::long2_type(), | |
965 VerificationType::long_type(), CHECK_VERIFY(this)); | |
966 current_frame.push_stack_2( | |
967 VerificationType::long_type(), | |
968 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
969 no_control_flow = false; break; | |
970 case Bytecodes::_fadd : | |
971 case Bytecodes::_fsub : | |
972 case Bytecodes::_fmul : | |
973 case Bytecodes::_fdiv : | |
974 case Bytecodes::_frem : | |
975 current_frame.pop_stack( | |
976 VerificationType::float_type(), CHECK_VERIFY(this)); | |
977 // fall through | |
978 case Bytecodes::_fneg : | |
979 current_frame.pop_stack( | |
980 VerificationType::float_type(), CHECK_VERIFY(this)); | |
981 current_frame.push_stack( | |
982 VerificationType::float_type(), CHECK_VERIFY(this)); | |
983 no_control_flow = false; break; | |
984 case Bytecodes::_dadd : | |
985 case Bytecodes::_dsub : | |
986 case Bytecodes::_dmul : | |
987 case Bytecodes::_ddiv : | |
988 case Bytecodes::_drem : | |
989 current_frame.pop_stack_2( | |
990 VerificationType::double2_type(), | |
991 VerificationType::double_type(), CHECK_VERIFY(this)); | |
992 // fall through | |
993 case Bytecodes::_dneg : | |
994 current_frame.pop_stack_2( | |
995 VerificationType::double2_type(), | |
996 VerificationType::double_type(), CHECK_VERIFY(this)); | |
997 current_frame.push_stack_2( | |
998 VerificationType::double_type(), | |
999 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
1000 no_control_flow = false; break; | |
1001 case Bytecodes::_iinc : | |
1002 verify_iinc(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); | |
1003 no_control_flow = false; break; | |
1004 case Bytecodes::_i2l : | |
1005 type = current_frame.pop_stack( | |
1006 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1007 current_frame.push_stack_2( | |
1008 VerificationType::long_type(), | |
1009 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
1010 no_control_flow = false; break; | |
1011 case Bytecodes::_l2i : | |
1012 current_frame.pop_stack_2( | |
1013 VerificationType::long2_type(), | |
1014 VerificationType::long_type(), CHECK_VERIFY(this)); | |
1015 current_frame.push_stack( | |
1016 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1017 no_control_flow = false; break; | |
1018 case Bytecodes::_i2f : | |
1019 current_frame.pop_stack( | |
1020 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1021 current_frame.push_stack( | |
1022 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1023 no_control_flow = false; break; | |
1024 case Bytecodes::_i2d : | |
1025 current_frame.pop_stack( | |
1026 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1027 current_frame.push_stack_2( | |
1028 VerificationType::double_type(), | |
1029 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
1030 no_control_flow = false; break; | |
1031 case Bytecodes::_l2f : | |
1032 current_frame.pop_stack_2( | |
1033 VerificationType::long2_type(), | |
1034 VerificationType::long_type(), CHECK_VERIFY(this)); | |
1035 current_frame.push_stack( | |
1036 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1037 no_control_flow = false; break; | |
1038 case Bytecodes::_l2d : | |
1039 current_frame.pop_stack_2( | |
1040 VerificationType::long2_type(), | |
1041 VerificationType::long_type(), CHECK_VERIFY(this)); | |
1042 current_frame.push_stack_2( | |
1043 VerificationType::double_type(), | |
1044 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
1045 no_control_flow = false; break; | |
1046 case Bytecodes::_f2i : | |
1047 current_frame.pop_stack( | |
1048 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1049 current_frame.push_stack( | |
1050 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1051 no_control_flow = false; break; | |
1052 case Bytecodes::_f2l : | |
1053 current_frame.pop_stack( | |
1054 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1055 current_frame.push_stack_2( | |
1056 VerificationType::long_type(), | |
1057 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
1058 no_control_flow = false; break; | |
1059 case Bytecodes::_f2d : | |
1060 current_frame.pop_stack( | |
1061 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1062 current_frame.push_stack_2( | |
1063 VerificationType::double_type(), | |
1064 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
1065 no_control_flow = false; break; | |
1066 case Bytecodes::_d2i : | |
1067 current_frame.pop_stack_2( | |
1068 VerificationType::double2_type(), | |
1069 VerificationType::double_type(), CHECK_VERIFY(this)); | |
1070 current_frame.push_stack( | |
1071 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1072 no_control_flow = false; break; | |
1073 case Bytecodes::_d2l : | |
1074 current_frame.pop_stack_2( | |
1075 VerificationType::double2_type(), | |
1076 VerificationType::double_type(), CHECK_VERIFY(this)); | |
1077 current_frame.push_stack_2( | |
1078 VerificationType::long_type(), | |
1079 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
1080 no_control_flow = false; break; | |
1081 case Bytecodes::_d2f : | |
1082 current_frame.pop_stack_2( | |
1083 VerificationType::double2_type(), | |
1084 VerificationType::double_type(), CHECK_VERIFY(this)); | |
1085 current_frame.push_stack( | |
1086 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1087 no_control_flow = false; break; | |
1088 case Bytecodes::_i2b : | |
1089 case Bytecodes::_i2c : | |
1090 case Bytecodes::_i2s : | |
1091 current_frame.pop_stack( | |
1092 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1093 current_frame.push_stack( | |
1094 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1095 no_control_flow = false; break; | |
1096 case Bytecodes::_lcmp : | |
1097 current_frame.pop_stack_2( | |
1098 VerificationType::long2_type(), | |
1099 VerificationType::long_type(), CHECK_VERIFY(this)); | |
1100 current_frame.pop_stack_2( | |
1101 VerificationType::long2_type(), | |
1102 VerificationType::long_type(), CHECK_VERIFY(this)); | |
1103 current_frame.push_stack( | |
1104 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1105 no_control_flow = false; break; | |
1106 case Bytecodes::_fcmpl : | |
1107 case Bytecodes::_fcmpg : | |
1108 current_frame.pop_stack( | |
1109 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1110 current_frame.pop_stack( | |
1111 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1112 current_frame.push_stack( | |
1113 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1114 no_control_flow = false; break; | |
1115 case Bytecodes::_dcmpl : | |
1116 case Bytecodes::_dcmpg : | |
1117 current_frame.pop_stack_2( | |
1118 VerificationType::double2_type(), | |
1119 VerificationType::double_type(), CHECK_VERIFY(this)); | |
1120 current_frame.pop_stack_2( | |
1121 VerificationType::double2_type(), | |
1122 VerificationType::double_type(), CHECK_VERIFY(this)); | |
1123 current_frame.push_stack( | |
1124 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1125 no_control_flow = false; break; | |
1126 case Bytecodes::_if_icmpeq: | |
1127 case Bytecodes::_if_icmpne: | |
1128 case Bytecodes::_if_icmplt: | |
1129 case Bytecodes::_if_icmpge: | |
1130 case Bytecodes::_if_icmpgt: | |
1131 case Bytecodes::_if_icmple: | |
1132 current_frame.pop_stack( | |
1133 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1134 // fall through | |
1135 case Bytecodes::_ifeq: | |
1136 case Bytecodes::_ifne: | |
1137 case Bytecodes::_iflt: | |
1138 case Bytecodes::_ifge: | |
1139 case Bytecodes::_ifgt: | |
1140 case Bytecodes::_ifle: | |
1141 current_frame.pop_stack( | |
1142 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1143 target = bcs.dest(); | |
1144 stackmap_table.check_jump_target( | |
1145 ¤t_frame, target, CHECK_VERIFY(this)); | |
1146 no_control_flow = false; break; | |
1147 case Bytecodes::_if_acmpeq : | |
1148 case Bytecodes::_if_acmpne : | |
1149 current_frame.pop_stack( | |
1150 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
1151 // fall through | |
1152 case Bytecodes::_ifnull : | |
1153 case Bytecodes::_ifnonnull : | |
1154 current_frame.pop_stack( | |
1155 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
1156 target = bcs.dest(); | |
1157 stackmap_table.check_jump_target | |
1158 (¤t_frame, target, CHECK_VERIFY(this)); | |
1159 no_control_flow = false; break; | |
1160 case Bytecodes::_goto : | |
1161 target = bcs.dest(); | |
1162 stackmap_table.check_jump_target( | |
1163 ¤t_frame, target, CHECK_VERIFY(this)); | |
1164 no_control_flow = true; break; | |
1165 case Bytecodes::_goto_w : | |
1166 target = bcs.dest_w(); | |
1167 stackmap_table.check_jump_target( | |
1168 ¤t_frame, target, CHECK_VERIFY(this)); | |
1169 no_control_flow = true; break; | |
1170 case Bytecodes::_tableswitch : | |
1171 case Bytecodes::_lookupswitch : | |
1172 verify_switch( | |
1173 &bcs, code_length, code_data, ¤t_frame, | |
1174 &stackmap_table, CHECK_VERIFY(this)); | |
1175 no_control_flow = true; break; | |
1176 case Bytecodes::_ireturn : | |
1177 type = current_frame.pop_stack( | |
1178 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1179 verify_return_value(return_type, type, bci, CHECK_VERIFY(this)); | |
1180 no_control_flow = true; break; | |
1181 case Bytecodes::_lreturn : | |
1182 type2 = current_frame.pop_stack( | |
1183 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
1184 type = current_frame.pop_stack( | |
1185 VerificationType::long_type(), CHECK_VERIFY(this)); | |
1186 verify_return_value(return_type, type, bci, CHECK_VERIFY(this)); | |
1187 no_control_flow = true; break; | |
1188 case Bytecodes::_freturn : | |
1189 type = current_frame.pop_stack( | |
1190 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1191 verify_return_value(return_type, type, bci, CHECK_VERIFY(this)); | |
1192 no_control_flow = true; break; | |
1193 case Bytecodes::_dreturn : | |
1194 type2 = current_frame.pop_stack( | |
1195 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
1196 type = current_frame.pop_stack( | |
1197 VerificationType::double_type(), CHECK_VERIFY(this)); | |
1198 verify_return_value(return_type, type, bci, CHECK_VERIFY(this)); | |
1199 no_control_flow = true; break; | |
1200 case Bytecodes::_areturn : | |
1201 type = current_frame.pop_stack( | |
1202 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
1203 verify_return_value(return_type, type, bci, CHECK_VERIFY(this)); | |
1204 no_control_flow = true; break; | |
1205 case Bytecodes::_return : | |
1206 if (return_type != VerificationType::bogus_type()) { | |
1207 verify_error(bci, "Method expects no return value"); | |
1208 return; | |
1209 } | |
1210 // Make sure "this" has been initialized if current method is an | |
1211 // <init> | |
1212 if (_method->name() == vmSymbols::object_initializer_name() && | |
1213 current_frame.flag_this_uninit()) { | |
1214 verify_error(bci, | |
1215 "Constructor must call super() or this() before return"); | |
1216 return; | |
1217 } | |
1218 no_control_flow = true; break; | |
1219 case Bytecodes::_getstatic : | |
1220 case Bytecodes::_putstatic : | |
1221 case Bytecodes::_getfield : | |
1222 case Bytecodes::_putfield : | |
1223 verify_field_instructions( | |
1224 &bcs, ¤t_frame, cp, CHECK_VERIFY(this)); | |
1225 no_control_flow = false; break; | |
1226 case Bytecodes::_invokevirtual : | |
1227 case Bytecodes::_invokespecial : | |
1228 case Bytecodes::_invokestatic : | |
1229 verify_invoke_instructions( | |
1230 &bcs, code_length, ¤t_frame, | |
1231 &this_uninit, return_type, cp, CHECK_VERIFY(this)); | |
1232 no_control_flow = false; break; | |
1233 case Bytecodes::_invokeinterface : | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1234 case Bytecodes::_invokedynamic : |
0 | 1235 verify_invoke_instructions( |
1236 &bcs, code_length, ¤t_frame, | |
1237 &this_uninit, return_type, cp, CHECK_VERIFY(this)); | |
1238 no_control_flow = false; break; | |
1239 case Bytecodes::_new : | |
1240 { | |
1565 | 1241 index = bcs.get_index_u2(); |
0 | 1242 verify_cp_class_type(index, cp, CHECK_VERIFY(this)); |
1243 VerificationType new_class_type = | |
1244 cp_index_to_type(index, cp, CHECK_VERIFY(this)); | |
1245 if (!new_class_type.is_object()) { | |
1246 verify_error(bci, "Illegal new instruction"); | |
1247 return; | |
1248 } | |
1249 type = VerificationType::uninitialized_type(bci); | |
1250 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
1251 no_control_flow = false; break; | |
1252 } | |
1253 case Bytecodes::_newarray : | |
1254 type = get_newarray_type(bcs.get_index(), bci, CHECK_VERIFY(this)); | |
1255 current_frame.pop_stack( | |
1256 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1257 current_frame.push_stack(type, CHECK_VERIFY(this)); | |
1258 no_control_flow = false; break; | |
1259 case Bytecodes::_anewarray : | |
1260 verify_anewarray( | |
1565 | 1261 bcs.get_index_u2(), cp, ¤t_frame, CHECK_VERIFY(this)); |
0 | 1262 no_control_flow = false; break; |
1263 case Bytecodes::_arraylength : | |
1264 type = current_frame.pop_stack( | |
1265 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
134
8a79f7ec8f5d
6692246: Regression : JDK 6u4 b01 fails two JCK tests when fallback is switched off
kamg
parents:
0
diff
changeset
|
1266 if (!(type.is_null() || type.is_array())) { |
0 | 1267 verify_error(bci, bad_type_msg, "arraylength"); |
1268 } | |
1269 current_frame.push_stack( | |
1270 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1271 no_control_flow = false; break; | |
1272 case Bytecodes::_checkcast : | |
1273 { | |
1565 | 1274 index = bcs.get_index_u2(); |
0 | 1275 verify_cp_class_type(index, cp, CHECK_VERIFY(this)); |
1955
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
1276 current_frame.pop_stack(object_type(), CHECK_VERIFY(this)); |
0 | 1277 VerificationType klass_type = cp_index_to_type( |
1278 index, cp, CHECK_VERIFY(this)); | |
1279 current_frame.push_stack(klass_type, CHECK_VERIFY(this)); | |
1280 no_control_flow = false; break; | |
1281 } | |
1282 case Bytecodes::_instanceof : { | |
1565 | 1283 index = bcs.get_index_u2(); |
0 | 1284 verify_cp_class_type(index, cp, CHECK_VERIFY(this)); |
1955
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
1285 current_frame.pop_stack(object_type(), CHECK_VERIFY(this)); |
0 | 1286 current_frame.push_stack( |
1287 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1288 no_control_flow = false; break; | |
1289 } | |
1290 case Bytecodes::_monitorenter : | |
1291 case Bytecodes::_monitorexit : | |
1292 current_frame.pop_stack( | |
1293 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
1294 no_control_flow = false; break; | |
1295 case Bytecodes::_multianewarray : | |
1296 { | |
1565 | 1297 index = bcs.get_index_u2(); |
0 | 1298 u2 dim = *(bcs.bcp()+3); |
1299 verify_cp_class_type(index, cp, CHECK_VERIFY(this)); | |
1300 VerificationType new_array_type = | |
1301 cp_index_to_type(index, cp, CHECK_VERIFY(this)); | |
1302 if (!new_array_type.is_array()) { | |
1303 verify_error(bci, | |
1304 "Illegal constant pool index in multianewarray instruction"); | |
1305 return; | |
1306 } | |
1307 if (dim < 1 || new_array_type.dimensions() < dim) { | |
1308 verify_error(bci, | |
1309 "Illegal dimension in multianewarray instruction"); | |
1310 return; | |
1311 } | |
1312 for (int i = 0; i < dim; i++) { | |
1313 current_frame.pop_stack( | |
1314 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1315 } | |
1316 current_frame.push_stack(new_array_type, CHECK_VERIFY(this)); | |
1317 no_control_flow = false; break; | |
1318 } | |
1319 case Bytecodes::_athrow : | |
1320 type = VerificationType::reference_type( | |
1321 vmSymbols::java_lang_Throwable()); | |
1322 current_frame.pop_stack(type, CHECK_VERIFY(this)); | |
1323 no_control_flow = true; break; | |
1324 default: | |
1325 // We only need to check the valid bytecodes in class file. | |
1326 // And jsr and ret are not in the new class file format in JDK1.5. | |
1327 verify_error(bci, "Bad instruction"); | |
1328 no_control_flow = false; | |
1329 return; | |
1330 } // end switch | |
1331 } // end Merge with the next instruction | |
1332 | |
1333 // Look for possible jump target in exception handlers and see if it | |
1334 // matches current_frame | |
1335 if (bci >= ex_min && bci < ex_max) { | |
1336 verify_exception_handler_targets( | |
1337 bci, this_uninit, ¤t_frame, &stackmap_table, CHECK_VERIFY(this)); | |
1338 } | |
1339 } // end while | |
1340 | |
1341 // Make sure that control flow does not fall through end of the method | |
1342 if (!no_control_flow) { | |
1343 verify_error(code_length, "Control flow falls through code end"); | |
1344 return; | |
1345 } | |
1346 } | |
1347 | |
1348 char* ClassVerifier::generate_code_data(methodHandle m, u4 code_length, TRAPS) { | |
1349 char* code_data = NEW_RESOURCE_ARRAY(char, code_length); | |
1350 memset(code_data, 0, sizeof(char) * code_length); | |
1351 RawBytecodeStream bcs(m); | |
1352 | |
1353 while (!bcs.is_last_bytecode()) { | |
1354 if (bcs.raw_next() != Bytecodes::_illegal) { | |
1355 int bci = bcs.bci(); | |
1565 | 1356 if (bcs.raw_code() == Bytecodes::_new) { |
0 | 1357 code_data[bci] = NEW_OFFSET; |
1358 } else { | |
1359 code_data[bci] = BYTECODE_OFFSET; | |
1360 } | |
1361 } else { | |
1362 verify_error(bcs.bci(), "Bad instruction"); | |
1363 return NULL; | |
1364 } | |
1365 } | |
1366 | |
1367 return code_data; | |
1368 } | |
1369 | |
1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) { | |
1371 typeArrayHandle exhandlers (THREAD, _method->exception_table()); | |
1372 constantPoolHandle cp (THREAD, _method->constants()); | |
1373 | |
1374 if (exhandlers() != NULL) { | |
1375 for(int i = 0; i < exhandlers->length();) { | |
1376 u2 start_pc = exhandlers->int_at(i++); | |
1377 u2 end_pc = exhandlers->int_at(i++); | |
1378 u2 handler_pc = exhandlers->int_at(i++); | |
1379 if (start_pc >= code_length || code_data[start_pc] == 0) { | |
1380 class_format_error("Illegal exception table start_pc %d", start_pc); | |
1381 return; | |
1382 } | |
1383 if (end_pc != code_length) { // special case: end_pc == code_length | |
1384 if (end_pc > code_length || code_data[end_pc] == 0) { | |
1385 class_format_error("Illegal exception table end_pc %d", end_pc); | |
1386 return; | |
1387 } | |
1388 } | |
1389 if (handler_pc >= code_length || code_data[handler_pc] == 0) { | |
1390 class_format_error("Illegal exception table handler_pc %d", handler_pc); | |
1391 return; | |
1392 } | |
1393 int catch_type_index = exhandlers->int_at(i++); | |
1394 if (catch_type_index != 0) { | |
1395 VerificationType catch_type = cp_index_to_type( | |
1396 catch_type_index, cp, CHECK_VERIFY(this)); | |
1397 VerificationType throwable = | |
1398 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); | |
1399 bool is_subclass = throwable.is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1400 catch_type, this, CHECK_VERIFY(this)); |
0 | 1401 if (!is_subclass) { |
1402 // 4286534: should throw VerifyError according to recent spec change | |
1403 verify_error( | |
1404 "Catch type is not a subclass of Throwable in handler %d", | |
1405 handler_pc); | |
1406 return; | |
1407 } | |
1408 } | |
1409 if (start_pc < min) min = start_pc; | |
1410 if (end_pc > max) max = end_pc; | |
1411 } | |
1412 } | |
1413 } | |
1414 | |
1415 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) { | |
1416 int localvariable_table_length = _method()->localvariable_table_length(); | |
1417 if (localvariable_table_length > 0) { | |
1418 LocalVariableTableElement* table = _method()->localvariable_table_start(); | |
1419 for (int i = 0; i < localvariable_table_length; i++) { | |
1420 u2 start_bci = table[i].start_bci; | |
1421 u2 length = table[i].length; | |
1422 | |
1423 if (start_bci >= code_length || code_data[start_bci] == 0) { | |
1424 class_format_error( | |
1425 "Illegal local variable table start_pc %d", start_bci); | |
1426 return; | |
1427 } | |
1428 u4 end_bci = (u4)(start_bci + length); | |
1429 if (end_bci != code_length) { | |
1430 if (end_bci >= code_length || code_data[end_bci] == 0) { | |
1431 class_format_error( "Illegal local variable table length %d", length); | |
1432 return; | |
1433 } | |
1434 } | |
1435 } | |
1436 } | |
1437 } | |
1438 | |
1439 u2 ClassVerifier::verify_stackmap_table(u2 stackmap_index, u2 bci, | |
1440 StackMapFrame* current_frame, | |
1441 StackMapTable* stackmap_table, | |
1442 bool no_control_flow, TRAPS) { | |
1443 if (stackmap_index < stackmap_table->get_frame_count()) { | |
1444 u2 this_offset = stackmap_table->get_offset(stackmap_index); | |
1445 if (no_control_flow && this_offset > bci) { | |
1446 verify_error(bci, "Expecting a stack map frame"); | |
1447 return 0; | |
1448 } | |
1449 if (this_offset == bci) { | |
1450 // See if current stack map can be assigned to the frame in table. | |
1451 // current_frame is the stackmap frame got from the last instruction. | |
1452 // If matched, current_frame will be updated by this method. | |
1453 bool match = stackmap_table->match_stackmap( | |
1454 current_frame, this_offset, stackmap_index, | |
1455 !no_control_flow, true, CHECK_VERIFY_(this, 0)); | |
1456 if (!match) { | |
1457 // report type error | |
1458 verify_error(bci, "Instruction type does not match stack map"); | |
1459 return 0; | |
1460 } | |
1461 stackmap_index++; | |
1462 } else if (this_offset < bci) { | |
1463 // current_offset should have met this_offset. | |
1464 class_format_error("Bad stack map offset %d", this_offset); | |
1465 return 0; | |
1466 } | |
1467 } else if (no_control_flow) { | |
1468 verify_error(bci, "Expecting a stack map frame"); | |
1469 return 0; | |
1470 } | |
1471 return stackmap_index; | |
1472 } | |
1473 | |
1474 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame, | |
1475 StackMapTable* stackmap_table, TRAPS) { | |
1476 constantPoolHandle cp (THREAD, _method->constants()); | |
1477 typeArrayHandle exhandlers (THREAD, _method->exception_table()); | |
1478 if (exhandlers() != NULL) { | |
1479 for(int i = 0; i < exhandlers->length();) { | |
1480 u2 start_pc = exhandlers->int_at(i++); | |
1481 u2 end_pc = exhandlers->int_at(i++); | |
1482 u2 handler_pc = exhandlers->int_at(i++); | |
1483 int catch_type_index = exhandlers->int_at(i++); | |
1484 if(bci >= start_pc && bci < end_pc) { | |
1485 u1 flags = current_frame->flags(); | |
1486 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } | |
1487 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); | |
1488 if (catch_type_index != 0) { | |
1489 // We know that this index refers to a subclass of Throwable | |
1490 VerificationType catch_type = cp_index_to_type( | |
1491 catch_type_index, cp, CHECK_VERIFY(this)); | |
1492 new_frame->push_stack(catch_type, CHECK_VERIFY(this)); | |
1493 } else { | |
1494 VerificationType throwable = | |
1495 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); | |
1496 new_frame->push_stack(throwable, CHECK_VERIFY(this)); | |
1497 } | |
1498 bool match = stackmap_table->match_stackmap( | |
1499 new_frame, handler_pc, true, false, CHECK_VERIFY(this)); | |
1500 if (!match) { | |
1501 verify_error(bci, | |
1502 "Stack map does not match the one at exception handler %d", | |
1503 handler_pc); | |
1504 return; | |
1505 } | |
1506 } | |
1507 } | |
1508 } | |
1509 } | |
1510 | |
1511 void ClassVerifier::verify_cp_index(constantPoolHandle cp, int index, TRAPS) { | |
1512 int nconstants = cp->length(); | |
1513 if ((index <= 0) || (index >= nconstants)) { | |
1514 verify_error("Illegal constant pool index %d in class %s", | |
1515 index, instanceKlass::cast(cp->pool_holder())->external_name()); | |
1516 return; | |
1517 } | |
1518 } | |
1519 | |
1520 void ClassVerifier::verify_cp_type( | |
1521 int index, constantPoolHandle cp, unsigned int types, TRAPS) { | |
1522 | |
1523 // In some situations, bytecode rewriting may occur while we're verifying. | |
1524 // In this case, a constant pool cache exists and some indices refer to that | |
1570 | 1525 // instead. Be sure we don't pick up such indices by accident. |
1526 // We must check was_recursively_verified() before we get here. | |
1527 guarantee(cp->cache() == NULL, "not rewritten yet"); | |
0 | 1528 |
1529 verify_cp_index(cp, index, CHECK_VERIFY(this)); | |
1530 unsigned int tag = cp->tag_at(index).value(); | |
1531 if ((types & (1 << tag)) == 0) { | |
1532 verify_error( | |
1533 "Illegal type at constant pool entry %d in class %s", | |
1534 index, instanceKlass::cast(cp->pool_holder())->external_name()); | |
1535 return; | |
1536 } | |
1537 } | |
1538 | |
1539 void ClassVerifier::verify_cp_class_type( | |
1540 int index, constantPoolHandle cp, TRAPS) { | |
1541 verify_cp_index(cp, index, CHECK_VERIFY(this)); | |
1542 constantTag tag = cp->tag_at(index); | |
1543 if (!tag.is_klass() && !tag.is_unresolved_klass()) { | |
1544 verify_error("Illegal type at constant pool entry %d in class %s", | |
1545 index, instanceKlass::cast(cp->pool_holder())->external_name()); | |
1546 return; | |
1547 } | |
1548 } | |
1549 | |
1550 void ClassVerifier::format_error_message( | |
1551 const char* fmt, int offset, va_list va) { | |
1552 ResourceMark rm(_thread); | |
1553 stringStream message(_message, _message_buffer_len); | |
1554 message.vprint(fmt, va); | |
1555 if (!_method.is_null()) { | |
1556 message.print(" in method %s", _method->name_and_sig_as_C_string()); | |
1557 } | |
1558 if (offset != -1) { | |
1559 message.print(" at offset %d", offset); | |
1560 } | |
1561 } | |
1562 | |
1563 void ClassVerifier::verify_error(u2 offset, const char* fmt, ...) { | |
1564 _exception_type = vmSymbols::java_lang_VerifyError(); | |
1565 va_list va; | |
1566 va_start(va, fmt); | |
1567 format_error_message(fmt, offset, va); | |
1568 va_end(va); | |
1569 } | |
1570 | |
1571 void ClassVerifier::verify_error(const char* fmt, ...) { | |
1572 _exception_type = vmSymbols::java_lang_VerifyError(); | |
1573 va_list va; | |
1574 va_start(va, fmt); | |
1575 format_error_message(fmt, -1, va); | |
1576 va_end(va); | |
1577 } | |
1578 | |
1579 void ClassVerifier::class_format_error(const char* msg, ...) { | |
1580 _exception_type = vmSymbols::java_lang_ClassFormatError(); | |
1581 va_list va; | |
1582 va_start(va, msg); | |
1583 format_error_message(msg, -1, va); | |
1584 va_end(va); | |
1585 } | |
1586 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1587 klassOop ClassVerifier::load_class(Symbol* name, TRAPS) { |
0 | 1588 // Get current loader and protection domain first. |
1589 oop loader = current_class()->class_loader(); | |
1590 oop protection_domain = current_class()->protection_domain(); | |
1591 | |
1592 return SystemDictionary::resolve_or_fail( | |
1593 name, Handle(THREAD, loader), Handle(THREAD, protection_domain), | |
1594 true, CHECK_NULL); | |
1595 } | |
1596 | |
1597 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, | |
1598 klassOop target_class, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1599 Symbol* field_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1600 Symbol* field_sig, |
0 | 1601 bool is_method) { |
1602 No_Safepoint_Verifier nosafepoint; | |
1603 | |
1604 // If target class isn't a super class of this class, we don't worry about this case | |
1605 if (!this_class->is_subclass_of(target_class)) { | |
1606 return false; | |
1607 } | |
1608 // Check if the specified method or field is protected | |
1609 instanceKlass* target_instance = instanceKlass::cast(target_class); | |
1610 fieldDescriptor fd; | |
1611 if (is_method) { | |
1612 methodOop m = target_instance->uncached_lookup_method(field_name, field_sig); | |
1613 if (m != NULL && m->is_protected()) { | |
1614 if (!this_class->is_same_class_package(m->method_holder())) { | |
1615 return true; | |
1616 } | |
1617 } | |
1618 } else { | |
1619 klassOop member_klass = target_instance->find_field(field_name, field_sig, &fd); | |
1620 if(member_klass != NULL && fd.is_protected()) { | |
1621 if (!this_class->is_same_class_package(member_klass)) { | |
1622 return true; | |
1623 } | |
1624 } | |
1625 } | |
1626 return false; | |
1627 } | |
1628 | |
1629 void ClassVerifier::verify_ldc( | |
1630 int opcode, u2 index, StackMapFrame *current_frame, | |
1631 constantPoolHandle cp, u2 bci, TRAPS) { | |
1632 verify_cp_index(cp, index, CHECK_VERIFY(this)); | |
1633 constantTag tag = cp->tag_at(index); | |
1634 unsigned int types; | |
1635 if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) { | |
1636 if (!tag.is_unresolved_string() && !tag.is_unresolved_klass()) { | |
1637 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float) | |
1602 | 1638 | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class) |
1639 | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType); | |
1640 // Note: The class file parser already verified the legality of | |
1641 // MethodHandle and MethodType constants. | |
0 | 1642 verify_cp_type(index, cp, types, CHECK_VERIFY(this)); |
1643 } | |
1644 } else { | |
1645 assert(opcode == Bytecodes::_ldc2_w, "must be ldc2_w"); | |
1646 types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long); | |
1647 verify_cp_type(index, cp, types, CHECK_VERIFY(this)); | |
1648 } | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
1649 if (tag.is_string() && cp->is_pseudo_string_at(index)) { |
1955
1070423b51f3
6865028: Illegal instructions passing verification prior to 'invokespecial Object.<init>'
kamg
parents:
1678
diff
changeset
|
1650 current_frame->push_stack(object_type(), CHECK_VERIFY(this)); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
1651 } else if (tag.is_string() || tag.is_unresolved_string()) { |
0 | 1652 current_frame->push_stack( |
1653 VerificationType::reference_type( | |
1654 vmSymbols::java_lang_String()), CHECK_VERIFY(this)); | |
1655 } else if (tag.is_klass() || tag.is_unresolved_klass()) { | |
1656 current_frame->push_stack( | |
1657 VerificationType::reference_type( | |
1658 vmSymbols::java_lang_Class()), CHECK_VERIFY(this)); | |
1659 } else if (tag.is_int()) { | |
1660 current_frame->push_stack( | |
1661 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1662 } else if (tag.is_float()) { | |
1663 current_frame->push_stack( | |
1664 VerificationType::float_type(), CHECK_VERIFY(this)); | |
1665 } else if (tag.is_double()) { | |
1666 current_frame->push_stack_2( | |
1667 VerificationType::double_type(), | |
1668 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
1669 } else if (tag.is_long()) { | |
1670 current_frame->push_stack_2( | |
1671 VerificationType::long_type(), | |
1672 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
1602 | 1673 } else if (tag.is_method_handle()) { |
1674 current_frame->push_stack( | |
1675 VerificationType::reference_type( | |
2460 | 1676 vmSymbols::java_lang_invoke_MethodHandle()), CHECK_VERIFY(this)); |
1602 | 1677 } else if (tag.is_method_type()) { |
1678 current_frame->push_stack( | |
1679 VerificationType::reference_type( | |
2460 | 1680 vmSymbols::java_lang_invoke_MethodType()), CHECK_VERIFY(this)); |
0 | 1681 } else { |
1682 verify_error(bci, "Invalid index in ldc"); | |
1683 return; | |
1684 } | |
1685 } | |
1686 | |
1687 void ClassVerifier::verify_switch( | |
1688 RawBytecodeStream* bcs, u4 code_length, char* code_data, | |
1689 StackMapFrame* current_frame, StackMapTable* stackmap_table, TRAPS) { | |
1690 int bci = bcs->bci(); | |
1691 address bcp = bcs->bcp(); | |
1692 address aligned_bcp = (address) round_to((intptr_t)(bcp + 1), jintSize); | |
1693 | |
1694 // 4639449 & 4647081: padding bytes must be 0 | |
1695 u2 padding_offset = 1; | |
1696 while ((bcp + padding_offset) < aligned_bcp) { | |
1697 if(*(bcp + padding_offset) != 0) { | |
1698 verify_error(bci, "Nonzero padding byte in lookswitch or tableswitch"); | |
1699 return; | |
1700 } | |
1701 padding_offset++; | |
1702 } | |
1703 int default_offset = (int) Bytes::get_Java_u4(aligned_bcp); | |
1704 int keys, delta; | |
1705 current_frame->pop_stack( | |
1706 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
1565 | 1707 if (bcs->raw_code() == Bytecodes::_tableswitch) { |
0 | 1708 jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize); |
1709 jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize); | |
1710 if (low > high) { | |
1711 verify_error(bci, | |
1712 "low must be less than or equal to high in tableswitch"); | |
1713 return; | |
1714 } | |
1715 keys = high - low + 1; | |
1716 if (keys < 0) { | |
1717 verify_error(bci, "too many keys in tableswitch"); | |
1718 return; | |
1719 } | |
1720 delta = 1; | |
1721 } else { | |
1722 keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize); | |
1723 if (keys < 0) { | |
1724 verify_error(bci, "number of keys in lookupswitch less than 0"); | |
1725 return; | |
1726 } | |
1727 delta = 2; | |
1728 // Make sure that the lookupswitch items are sorted | |
1729 for (int i = 0; i < (keys - 1); i++) { | |
1730 jint this_key = Bytes::get_Java_u4(aligned_bcp + (2+2*i)*jintSize); | |
1731 jint next_key = Bytes::get_Java_u4(aligned_bcp + (2+2*i+2)*jintSize); | |
1732 if (this_key >= next_key) { | |
1733 verify_error(bci, "Bad lookupswitch instruction"); | |
1734 return; | |
1735 } | |
1736 } | |
1737 } | |
1738 int target = bci + default_offset; | |
1739 stackmap_table->check_jump_target(current_frame, target, CHECK_VERIFY(this)); | |
1740 for (int i = 0; i < keys; i++) { | |
1741 target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize); | |
1742 stackmap_table->check_jump_target( | |
1743 current_frame, target, CHECK_VERIFY(this)); | |
1744 } | |
1745 } | |
1746 | |
1747 bool ClassVerifier::name_in_supers( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1748 Symbol* ref_name, instanceKlassHandle current) { |
0 | 1749 klassOop super = current->super(); |
1750 while (super != NULL) { | |
1751 if (super->klass_part()->name() == ref_name) { | |
1752 return true; | |
1753 } | |
1754 super = super->klass_part()->super(); | |
1755 } | |
1756 return false; | |
1757 } | |
1758 | |
1759 void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs, | |
1760 StackMapFrame* current_frame, | |
1761 constantPoolHandle cp, | |
1762 TRAPS) { | |
1565 | 1763 u2 index = bcs->get_index_u2(); |
0 | 1764 verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); |
1765 | |
1766 // Get field name and signature | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1767 Symbol* field_name = cp->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1768 Symbol* field_sig = cp->signature_ref_at(index); |
0 | 1769 |
1770 if (!SignatureVerifier::is_valid_type_signature(field_sig)) { | |
1771 class_format_error( | |
1772 "Invalid signature for field in class %s referenced " | |
1773 "from constant pool index %d", _klass->external_name(), index); | |
1774 return; | |
1775 } | |
1776 | |
1777 // Get referenced class type | |
1778 VerificationType ref_class_type = cp_ref_index_to_type( | |
1779 index, cp, CHECK_VERIFY(this)); | |
1780 if (!ref_class_type.is_object()) { | |
1781 verify_error( | |
1782 "Expecting reference to class in class %s at constant pool index %d", | |
1783 _klass->external_name(), index); | |
1784 return; | |
1785 } | |
1786 VerificationType target_class_type = ref_class_type; | |
1787 | |
1788 assert(sizeof(VerificationType) == sizeof(uintptr_t), | |
1789 "buffer type must match VerificationType size"); | |
1790 uintptr_t field_type_buffer[2]; | |
1791 VerificationType* field_type = (VerificationType*)field_type_buffer; | |
1792 // If we make a VerificationType[2] array directly, the compiler calls | |
1793 // to the c-runtime library to do the allocation instead of just | |
1794 // stack allocating it. Plus it would run constructors. This shows up | |
1795 // in performance profiles. | |
1796 | |
1797 SignatureStream sig_stream(field_sig, false); | |
1798 VerificationType stack_object_type; | |
1799 int n = change_sig_to_verificationType( | |
1800 &sig_stream, field_type, CHECK_VERIFY(this)); | |
1801 u2 bci = bcs->bci(); | |
1802 bool is_assignable; | |
1565 | 1803 switch (bcs->raw_code()) { |
0 | 1804 case Bytecodes::_getstatic: { |
1805 for (int i = 0; i < n; i++) { | |
1806 current_frame->push_stack(field_type[i], CHECK_VERIFY(this)); | |
1807 } | |
1808 break; | |
1809 } | |
1810 case Bytecodes::_putstatic: { | |
1811 for (int i = n - 1; i >= 0; i--) { | |
1812 current_frame->pop_stack(field_type[i], CHECK_VERIFY(this)); | |
1813 } | |
1814 break; | |
1815 } | |
1816 case Bytecodes::_getfield: { | |
1817 stack_object_type = current_frame->pop_stack( | |
1818 target_class_type, CHECK_VERIFY(this)); | |
1819 for (int i = 0; i < n; i++) { | |
1820 current_frame->push_stack(field_type[i], CHECK_VERIFY(this)); | |
1821 } | |
1822 goto check_protected; | |
1823 } | |
1824 case Bytecodes::_putfield: { | |
1825 for (int i = n - 1; i >= 0; i--) { | |
1826 current_frame->pop_stack(field_type[i], CHECK_VERIFY(this)); | |
1827 } | |
1828 stack_object_type = current_frame->pop_stack(CHECK_VERIFY(this)); | |
1829 | |
1830 // The JVMS 2nd edition allows field initialization before the superclass | |
1831 // initializer, if the field is defined within the current class. | |
1832 fieldDescriptor fd; | |
1833 if (stack_object_type == VerificationType::uninitialized_this_type() && | |
1834 target_class_type.equals(current_type()) && | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1835 _klass->find_local_field(field_name, field_sig, &fd)) { |
0 | 1836 stack_object_type = current_type(); |
1837 } | |
1838 is_assignable = target_class_type.is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1839 stack_object_type, this, CHECK_VERIFY(this)); |
0 | 1840 if (!is_assignable) { |
1841 verify_error(bci, "Bad type on operand stack in putfield"); | |
1842 return; | |
1843 } | |
1844 } | |
1845 check_protected: { | |
1846 if (_this_type == stack_object_type) | |
1847 break; // stack_object_type must be assignable to _current_class_type | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1848 Symbol* ref_class_name = |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1849 cp->klass_name_at(cp->klass_ref_index_at(index)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1850 if (!name_in_supers(ref_class_name, current_class())) |
0 | 1851 // stack_object_type must be assignable to _current_class_type since: |
1852 // 1. stack_object_type must be assignable to ref_class. | |
1853 // 2. ref_class must be _current_class or a subclass of it. It can't | |
1854 // be a superclass of it. See revised JVMS 5.4.4. | |
1855 break; | |
1856 | |
1857 klassOop ref_class_oop = load_class(ref_class_name, CHECK); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1858 if (is_protected_access(current_class(), ref_class_oop, field_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1859 field_sig, false)) { |
0 | 1860 // It's protected access, check if stack object is assignable to |
1861 // current class. | |
1862 is_assignable = current_type().is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1863 stack_object_type, this, CHECK_VERIFY(this)); |
0 | 1864 if (!is_assignable) { |
1865 verify_error(bci, "Bad access to protected data in getfield"); | |
1866 return; | |
1867 } | |
1868 } | |
1869 break; | |
1870 } | |
1871 default: ShouldNotReachHere(); | |
1872 } | |
1873 } | |
1874 | |
1875 void ClassVerifier::verify_invoke_init( | |
1876 RawBytecodeStream* bcs, VerificationType ref_class_type, | |
1877 StackMapFrame* current_frame, u4 code_length, bool *this_uninit, | |
1878 constantPoolHandle cp, TRAPS) { | |
1879 u2 bci = bcs->bci(); | |
1880 VerificationType type = current_frame->pop_stack( | |
1881 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
1882 if (type == VerificationType::uninitialized_this_type()) { | |
1883 // The method must be an <init> method of either this class, or one of its | |
1884 // superclasses | |
1677 | 1885 if (ref_class_type.name() != current_class()->name() && |
1886 !name_in_supers(ref_class_type.name(), current_class())) { | |
0 | 1887 verify_error(bci, "Bad <init> method call"); |
1888 return; | |
1889 } | |
1890 current_frame->initialize_object(type, current_type()); | |
1891 *this_uninit = true; | |
1892 } else if (type.is_uninitialized()) { | |
1893 u2 new_offset = type.bci(); | |
1894 address new_bcp = bcs->bcp() - bci + new_offset; | |
1895 if (new_offset > (code_length - 3) || (*new_bcp) != Bytecodes::_new) { | |
1896 verify_error(new_offset, "Expecting new instruction"); | |
1897 return; | |
1898 } | |
1899 u2 new_class_index = Bytes::get_Java_u2(new_bcp + 1); | |
1900 verify_cp_class_type(new_class_index, cp, CHECK_VERIFY(this)); | |
1901 | |
1902 // The method must be an <init> method of the indicated class | |
1903 VerificationType new_class_type = cp_index_to_type( | |
1904 new_class_index, cp, CHECK_VERIFY(this)); | |
1905 if (!new_class_type.equals(ref_class_type)) { | |
1906 verify_error(bci, "Call to wrong <init> method"); | |
1907 return; | |
1908 } | |
1909 // According to the VM spec, if the referent class is a superclass of the | |
1910 // current class, and is in a different runtime package, and the method is | |
1911 // protected, then the objectref must be the current class or a subclass | |
1912 // of the current class. | |
1913 VerificationType objectref_type = new_class_type; | |
1914 if (name_in_supers(ref_class_type.name(), current_class())) { | |
1915 klassOop ref_klass = load_class( | |
1916 ref_class_type.name(), CHECK_VERIFY(this)); | |
1917 methodOop m = instanceKlass::cast(ref_klass)->uncached_lookup_method( | |
1918 vmSymbols::object_initializer_name(), | |
1565 | 1919 cp->signature_ref_at(bcs->get_index_u2())); |
0 | 1920 instanceKlassHandle mh(THREAD, m->method_holder()); |
1921 if (m->is_protected() && !mh->is_same_class_package(_klass())) { | |
1922 bool assignable = current_type().is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1923 objectref_type, this, CHECK_VERIFY(this)); |
0 | 1924 if (!assignable) { |
1925 verify_error(bci, "Bad access to protected <init> method"); | |
1926 return; | |
1927 } | |
1928 } | |
1929 } | |
1930 current_frame->initialize_object(type, new_class_type); | |
1931 } else { | |
1932 verify_error(bci, "Bad operand type when invoking <init>"); | |
1933 return; | |
1934 } | |
1935 } | |
1936 | |
1937 void ClassVerifier::verify_invoke_instructions( | |
1938 RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, | |
1939 bool *this_uninit, VerificationType return_type, | |
1940 constantPoolHandle cp, TRAPS) { | |
1941 // Make sure the constant pool item is the right type | |
1565 | 1942 u2 index = bcs->get_index_u2(); |
1943 Bytecodes::Code opcode = bcs->raw_code(); | |
0 | 1944 unsigned int types = (opcode == Bytecodes::_invokeinterface |
1945 ? 1 << JVM_CONSTANT_InterfaceMethodref | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1946 : opcode == Bytecodes::_invokedynamic |
2460 | 1947 ? 1 << JVM_CONSTANT_InvokeDynamic |
0 | 1948 : 1 << JVM_CONSTANT_Methodref); |
1949 verify_cp_type(index, cp, types, CHECK_VERIFY(this)); | |
1950 | |
1951 // Get method name and signature | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1952 Symbol* method_name = cp->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
1953 Symbol* method_sig = cp->signature_ref_at(index); |
0 | 1954 |
1955 if (!SignatureVerifier::is_valid_method_signature(method_sig)) { | |
1956 class_format_error( | |
1957 "Invalid method signature in class %s referenced " | |
1958 "from constant pool index %d", _klass->external_name(), index); | |
1959 return; | |
1960 } | |
1961 | |
1962 // Get referenced class type | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1963 VerificationType ref_class_type; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1964 if (opcode == Bytecodes::_invokedynamic) { |
1602 | 1965 if (!EnableInvokeDynamic || |
1966 _klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1967 class_format_error( |
1602 | 1968 (!EnableInvokeDynamic ? |
1969 "invokedynamic instructions not enabled in this JVM" : | |
1970 "invokedynamic instructions not supported by this class file version"), | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1971 _klass->external_name()); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1972 return; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1973 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1974 } else { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1975 ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this)); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
1976 } |
0 | 1977 |
1978 // For a small signature length, we just allocate 128 bytes instead | |
1979 // of parsing the signature once to find its size. | |
1980 // -3 is for '(', ')' and return descriptor; multiply by 2 is for | |
1981 // longs/doubles to be consertive. | |
1982 assert(sizeof(VerificationType) == sizeof(uintptr_t), | |
1983 "buffer type must match VerificationType size"); | |
1984 uintptr_t on_stack_sig_types_buffer[128]; | |
1985 // If we make a VerificationType[128] array directly, the compiler calls | |
1986 // to the c-runtime library to do the allocation instead of just | |
1987 // stack allocating it. Plus it would run constructors. This shows up | |
1988 // in performance profiles. | |
1989 | |
1990 VerificationType* sig_types; | |
1991 int size = (method_sig->utf8_length() - 3) * 2; | |
1992 if (size > 128) { | |
1993 // Long and double occupies two slots here. | |
1994 ArgumentSizeComputer size_it(method_sig); | |
1995 size = size_it.size(); | |
1996 sig_types = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, size); | |
1997 } else{ | |
1998 sig_types = (VerificationType*)on_stack_sig_types_buffer; | |
1999 } | |
2000 SignatureStream sig_stream(method_sig); | |
2001 int sig_i = 0; | |
2002 while (!sig_stream.at_return_type()) { | |
2003 sig_i += change_sig_to_verificationType( | |
2004 &sig_stream, &sig_types[sig_i], CHECK_VERIFY(this)); | |
2005 sig_stream.next(); | |
2006 } | |
2007 int nargs = sig_i; | |
2008 | |
2009 #ifdef ASSERT | |
2010 { | |
2011 ArgumentSizeComputer size_it(method_sig); | |
2012 assert(nargs == size_it.size(), "Argument sizes do not match"); | |
2013 assert(nargs <= (method_sig->utf8_length() - 3) * 2, "estimate of max size isn't conservative enough"); | |
2014 } | |
2015 #endif | |
2016 | |
2017 // Check instruction operands | |
2018 u2 bci = bcs->bci(); | |
2019 if (opcode == Bytecodes::_invokeinterface) { | |
2020 address bcp = bcs->bcp(); | |
2021 // 4905268: count operand in invokeinterface should be nargs+1, not nargs. | |
2022 // JSR202 spec: The count operand of an invokeinterface instruction is valid if it is | |
2023 // the difference between the size of the operand stack before and after the instruction | |
2024 // executes. | |
2025 if (*(bcp+3) != (nargs+1)) { | |
2026 verify_error(bci, "Inconsistent args count operand in invokeinterface"); | |
2027 return; | |
2028 } | |
2029 if (*(bcp+4) != 0) { | |
2030 verify_error(bci, "Fourth operand byte of invokeinterface must be zero"); | |
2031 return; | |
2032 } | |
2033 } | |
2034 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2035 if (opcode == Bytecodes::_invokedynamic) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2036 address bcp = bcs->bcp(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2037 if (*(bcp+3) != 0 || *(bcp+4) != 0) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2038 verify_error(bci, "Third and fourth operand bytes of invokedynamic must be zero"); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2039 return; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2040 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2041 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2042 |
0 | 2043 if (method_name->byte_at(0) == '<') { |
2044 // Make sure <init> can only be invoked by invokespecial | |
2045 if (opcode != Bytecodes::_invokespecial || | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2046 method_name != vmSymbols::object_initializer_name()) { |
0 | 2047 verify_error(bci, "Illegal call to internal method"); |
2048 return; | |
2049 } | |
2050 } else if (opcode == Bytecodes::_invokespecial | |
2051 && !ref_class_type.equals(current_type()) | |
2052 && !ref_class_type.equals(VerificationType::reference_type( | |
2053 current_class()->super()->klass_part()->name()))) { | |
2054 bool subtype = ref_class_type.is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2055 current_type(), this, CHECK_VERIFY(this)); |
0 | 2056 if (!subtype) { |
2057 verify_error(bci, "Bad invokespecial instruction: " | |
2058 "current class isn't assignable to reference class."); | |
2059 return; | |
2060 } | |
2061 } | |
2062 // Match method descriptor with operand stack | |
2063 for (int i = nargs - 1; i >= 0; i--) { // Run backwards | |
2064 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); | |
2065 } | |
2066 // Check objectref on operand stack | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2067 if (opcode != Bytecodes::_invokestatic && |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
431
diff
changeset
|
2068 opcode != Bytecodes::_invokedynamic) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2069 if (method_name == vmSymbols::object_initializer_name()) { // <init> method |
0 | 2070 verify_invoke_init(bcs, ref_class_type, current_frame, |
2071 code_length, this_uninit, cp, CHECK_VERIFY(this)); | |
2072 } else { // other methods | |
2073 // Ensures that target class is assignable to method class. | |
2074 if (opcode == Bytecodes::_invokespecial) { | |
2075 current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); | |
2076 } else if (opcode == Bytecodes::_invokevirtual) { | |
2077 VerificationType stack_object_type = | |
2078 current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); | |
2079 if (current_type() != stack_object_type) { | |
2080 assert(cp->cache() == NULL, "not rewritten yet"); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2081 Symbol* ref_class_name = |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2082 cp->klass_name_at(cp->klass_ref_index_at(index)); |
0 | 2083 // See the comments in verify_field_instructions() for |
2084 // the rationale behind this. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2085 if (name_in_supers(ref_class_name, current_class())) { |
0 | 2086 klassOop ref_class = load_class(ref_class_name, CHECK); |
2087 if (is_protected_access( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2088 _klass, ref_class, method_name, method_sig, true)) { |
0 | 2089 // It's protected access, check if stack object is |
2090 // assignable to current class. | |
2091 bool is_assignable = current_type().is_assignable_from( | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2092 stack_object_type, this, CHECK_VERIFY(this)); |
0 | 2093 if (!is_assignable) { |
2094 if (ref_class_type.name() == vmSymbols::java_lang_Object() | |
2095 && stack_object_type.is_array() | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2096 && method_name == vmSymbols::clone_name()) { |
0 | 2097 // Special case: arrays pretend to implement public Object |
2098 // clone(). | |
2099 } else { | |
2100 verify_error(bci, | |
2101 "Bad access to protected data in invokevirtual"); | |
2102 return; | |
2103 } | |
2104 } | |
2105 } | |
2106 } | |
2107 } | |
2108 } else { | |
2109 assert(opcode == Bytecodes::_invokeinterface, "Unexpected opcode encountered"); | |
2110 current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); | |
2111 } | |
2112 } | |
2113 } | |
2114 // Push the result type. | |
2115 if (sig_stream.type() != T_VOID) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2116 if (method_name == vmSymbols::object_initializer_name()) { |
0 | 2117 // <init> method must have a void return type |
2118 verify_error(bci, "Return type must be void in <init> method"); | |
2119 return; | |
2120 } | |
2121 VerificationType return_type[2]; | |
2122 int n = change_sig_to_verificationType( | |
2123 &sig_stream, return_type, CHECK_VERIFY(this)); | |
2124 for (int i = 0; i < n; i++) { | |
2125 current_frame->push_stack(return_type[i], CHECK_VERIFY(this)); // push types backwards | |
2126 } | |
2127 } | |
2128 } | |
2129 | |
2130 VerificationType ClassVerifier::get_newarray_type( | |
2131 u2 index, u2 bci, TRAPS) { | |
2132 const char* from_bt[] = { | |
2133 NULL, NULL, NULL, NULL, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J", | |
2134 }; | |
2135 if (index < T_BOOLEAN || index > T_LONG) { | |
2136 verify_error(bci, "Illegal newarray instruction"); | |
2137 return VerificationType::bogus_type(); | |
2138 } | |
2139 | |
2140 // from_bt[index] contains the array signature which has a length of 2 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2141 Symbol* sig = create_temporary_symbol( |
0 | 2142 from_bt[index], 2, CHECK_(VerificationType::bogus_type())); |
2143 return VerificationType::reference_type(sig); | |
2144 } | |
2145 | |
2146 void ClassVerifier::verify_anewarray( | |
2147 u2 index, constantPoolHandle cp, StackMapFrame* current_frame, TRAPS) { | |
2148 verify_cp_class_type(index, cp, CHECK_VERIFY(this)); | |
2149 current_frame->pop_stack( | |
2150 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
2151 | |
2152 VerificationType component_type = | |
2153 cp_index_to_type(index, cp, CHECK_VERIFY(this)); | |
2154 int length; | |
2155 char* arr_sig_str; | |
2156 if (component_type.is_array()) { // it's an array | |
2157 const char* component_name = component_type.name()->as_utf8(); | |
2158 // add one dimension to component | |
2159 length = (int)strlen(component_name) + 1; | |
2160 arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length); | |
2161 arr_sig_str[0] = '['; | |
2162 strncpy(&arr_sig_str[1], component_name, length - 1); | |
2163 } else { // it's an object or interface | |
2164 const char* component_name = component_type.name()->as_utf8(); | |
2165 // add one dimension to component with 'L' prepended and ';' postpended. | |
2166 length = (int)strlen(component_name) + 3; | |
2167 arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length); | |
2168 arr_sig_str[0] = '['; | |
2169 arr_sig_str[1] = 'L'; | |
2170 strncpy(&arr_sig_str[2], component_name, length - 2); | |
2171 arr_sig_str[length - 1] = ';'; | |
2172 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2173 Symbol* arr_sig = create_temporary_symbol( |
0 | 2174 arr_sig_str, length, CHECK_VERIFY(this)); |
2175 VerificationType new_array_type = VerificationType::reference_type(arr_sig); | |
2176 current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); | |
2177 } | |
2178 | |
2179 void ClassVerifier::verify_iload(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2180 current_frame->get_local( | |
2181 index, VerificationType::integer_type(), CHECK_VERIFY(this)); | |
2182 current_frame->push_stack( | |
2183 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
2184 } | |
2185 | |
2186 void ClassVerifier::verify_lload(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2187 current_frame->get_local_2( | |
2188 index, VerificationType::long_type(), | |
2189 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
2190 current_frame->push_stack_2( | |
2191 VerificationType::long_type(), | |
2192 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
2193 } | |
2194 | |
2195 void ClassVerifier::verify_fload(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2196 current_frame->get_local( | |
2197 index, VerificationType::float_type(), CHECK_VERIFY(this)); | |
2198 current_frame->push_stack( | |
2199 VerificationType::float_type(), CHECK_VERIFY(this)); | |
2200 } | |
2201 | |
2202 void ClassVerifier::verify_dload(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2203 current_frame->get_local_2( | |
2204 index, VerificationType::double_type(), | |
2205 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
2206 current_frame->push_stack_2( | |
2207 VerificationType::double_type(), | |
2208 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
2209 } | |
2210 | |
2211 void ClassVerifier::verify_aload(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2212 VerificationType type = current_frame->get_local( | |
2213 index, VerificationType::reference_check(), CHECK_VERIFY(this)); | |
2214 current_frame->push_stack(type, CHECK_VERIFY(this)); | |
2215 } | |
2216 | |
2217 void ClassVerifier::verify_istore(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2218 current_frame->pop_stack( | |
2219 VerificationType::integer_type(), CHECK_VERIFY(this)); | |
2220 current_frame->set_local( | |
2221 index, VerificationType::integer_type(), CHECK_VERIFY(this)); | |
2222 } | |
2223 | |
2224 void ClassVerifier::verify_lstore(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2225 current_frame->pop_stack_2( | |
2226 VerificationType::long2_type(), | |
2227 VerificationType::long_type(), CHECK_VERIFY(this)); | |
2228 current_frame->set_local_2( | |
2229 index, VerificationType::long_type(), | |
2230 VerificationType::long2_type(), CHECK_VERIFY(this)); | |
2231 } | |
2232 | |
2233 void ClassVerifier::verify_fstore(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2234 current_frame->pop_stack(VerificationType::float_type(), CHECK_VERIFY(this)); | |
2235 current_frame->set_local( | |
2236 index, VerificationType::float_type(), CHECK_VERIFY(this)); | |
2237 } | |
2238 | |
2239 void ClassVerifier::verify_dstore(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2240 current_frame->pop_stack_2( | |
2241 VerificationType::double2_type(), | |
2242 VerificationType::double_type(), CHECK_VERIFY(this)); | |
2243 current_frame->set_local_2( | |
2244 index, VerificationType::double_type(), | |
2245 VerificationType::double2_type(), CHECK_VERIFY(this)); | |
2246 } | |
2247 | |
2248 void ClassVerifier::verify_astore(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2249 VerificationType type = current_frame->pop_stack( | |
2250 VerificationType::reference_check(), CHECK_VERIFY(this)); | |
2251 current_frame->set_local(index, type, CHECK_VERIFY(this)); | |
2252 } | |
2253 | |
2254 void ClassVerifier::verify_iinc(u2 index, StackMapFrame* current_frame, TRAPS) { | |
2255 VerificationType type = current_frame->get_local( | |
2256 index, VerificationType::integer_type(), CHECK_VERIFY(this)); | |
2257 current_frame->set_local(index, type, CHECK_VERIFY(this)); | |
2258 } | |
2259 | |
2260 void ClassVerifier::verify_return_value( | |
2261 VerificationType return_type, VerificationType type, u2 bci, TRAPS) { | |
2262 if (return_type == VerificationType::bogus_type()) { | |
2263 verify_error(bci, "Method expects a return value"); | |
2264 return; | |
2265 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2266 bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this)); |
0 | 2267 if (!match) { |
2268 verify_error(bci, "Bad return type"); | |
2269 return; | |
2270 } | |
2271 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2272 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2273 // The verifier creates symbols which are substrings of Symbols. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2274 // These are stored in the verifier until the end of verification so that |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2275 // they can be reference counted. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2276 Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2277 int end, TRAPS) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2278 Symbol* sym = SymbolTable::new_symbol(s, begin, end, CHECK_NULL); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2279 _symbols->push(sym); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2280 return sym; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2281 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2282 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2283 Symbol* ClassVerifier::create_temporary_symbol(const char *s, int length, TRAPS) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2284 Symbol* sym = SymbolTable::new_symbol(s, length, CHECK_NULL); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2285 _symbols->push(sym); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2286 return sym; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
2287 } |