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