Mercurial > hg > truffle
comparison src/share/vm/classfile/verifier.cpp @ 2177:3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
author | coleenp |
---|---|
date | Thu, 27 Jan 2011 16:11:27 -0800 |
parents | 828eafbd85cc |
children | b92c45f2bc75 |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
96 (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted); | 96 (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted); |
97 return !need_verify; | 97 return !need_verify; |
98 } | 98 } |
99 | 99 |
100 bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) { | 100 bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) { |
101 HandleMark hm; | |
101 ResourceMark rm(THREAD); | 102 ResourceMark rm(THREAD); |
102 HandleMark hm; | 103 |
103 | 104 Symbol* exception_name = NULL; |
104 symbolHandle exception_name; | |
105 const size_t message_buffer_len = klass->name()->utf8_length() + 1024; | 105 const size_t message_buffer_len = klass->name()->utf8_length() + 1024; |
106 char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); | 106 char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); |
107 | 107 |
108 const char* klassName = klass->external_name(); | 108 const char* klassName = klass->external_name(); |
109 | 109 |
139 if (TraceClassInitialization) { | 139 if (TraceClassInitialization) { |
140 if (HAS_PENDING_EXCEPTION) { | 140 if (HAS_PENDING_EXCEPTION) { |
141 tty->print("Verification for %s has", klassName); | 141 tty->print("Verification for %s has", klassName); |
142 tty->print_cr(" exception pending %s ", | 142 tty->print_cr(" exception pending %s ", |
143 instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); | 143 instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); |
144 } else if (!exception_name.is_null()) { | 144 } else if (exception_name != NULL) { |
145 tty->print_cr("Verification for %s failed", klassName); | 145 tty->print_cr("Verification for %s failed", klassName); |
146 } | 146 } |
147 tty->print_cr("End class verification for: %s", klassName); | 147 tty->print_cr("End class verification for: %s", klassName); |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 if (HAS_PENDING_EXCEPTION) { | 151 if (HAS_PENDING_EXCEPTION) { |
152 return false; // use the existing exception | 152 return false; // use the existing exception |
153 } else if (exception_name.is_null()) { | 153 } else if (exception_name == NULL) { |
154 return true; // verifcation succeeded | 154 return true; // verifcation succeeded |
155 } else { // VerifyError or ClassFormatError to be created and thrown | 155 } else { // VerifyError or ClassFormatError to be created and thrown |
156 ResourceMark rm(THREAD); | 156 ResourceMark rm(THREAD); |
157 instanceKlassHandle kls = | 157 instanceKlassHandle kls = |
158 SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false); | 158 SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false); |
170 THROW_MSG_(exception_name, message_buffer, false); | 170 THROW_MSG_(exception_name, message_buffer, false); |
171 } | 171 } |
172 } | 172 } |
173 | 173 |
174 bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { | 174 bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { |
175 symbolOop name = klass->name(); | 175 Symbol* name = klass->name(); |
176 klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); | 176 klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); |
177 | 177 |
178 return (should_verify_for(klass->class_loader(), should_verify_class) && | 178 return (should_verify_for(klass->class_loader(), should_verify_class) && |
179 // return if the class is a bootstrapping class | 179 // return if the class is a bootstrapping class |
180 // or defineClass specified not to verify by default (flags override passed arg) | 180 // or defineClass specified not to verify by default (flags override passed arg) |
200 !klass->is_subtype_of(refl_magic_klass) || | 200 !klass->is_subtype_of(refl_magic_klass) || |
201 VerifyReflectionBytecodes) | 201 VerifyReflectionBytecodes) |
202 ); | 202 ); |
203 } | 203 } |
204 | 204 |
205 symbolHandle Verifier::inference_verify( | 205 Symbol* Verifier::inference_verify( |
206 instanceKlassHandle klass, char* message, size_t message_len, TRAPS) { | 206 instanceKlassHandle klass, char* message, size_t message_len, TRAPS) { |
207 JavaThread* thread = (JavaThread*)THREAD; | 207 JavaThread* thread = (JavaThread*)THREAD; |
208 JNIEnv *env = thread->jni_environment(); | 208 JNIEnv *env = thread->jni_environment(); |
209 | 209 |
210 void* verify_func = verify_byte_codes_fn(); | 210 void* verify_func = verify_byte_codes_fn(); |
243 JNIHandles::destroy_local(cls); | 243 JNIHandles::destroy_local(cls); |
244 | 244 |
245 // These numbers are chosen so that VerifyClassCodes interface doesn't need | 245 // These numbers are chosen so that VerifyClassCodes interface doesn't need |
246 // to be changed (still return jboolean (unsigned char)), and result is | 246 // to be changed (still return jboolean (unsigned char)), and result is |
247 // 1 when verification is passed. | 247 // 1 when verification is passed. |
248 symbolHandle nh(NULL); | |
249 if (result == 0) { | 248 if (result == 0) { |
250 return vmSymbols::java_lang_VerifyError(); | 249 return vmSymbols::java_lang_VerifyError(); |
251 } else if (result == 1) { | 250 } else if (result == 1) { |
252 return nh; // verified. | 251 return NULL; // verified. |
253 } else if (result == 2) { | 252 } else if (result == 2) { |
254 THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, nh); | 253 THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL); |
255 } else if (result == 3) { | 254 } else if (result == 3) { |
256 return vmSymbols::java_lang_ClassFormatError(); | 255 return vmSymbols::java_lang_ClassFormatError(); |
257 } else { | 256 } else { |
258 ShouldNotReachHere(); | 257 ShouldNotReachHere(); |
259 return nh; | 258 return NULL; |
260 } | 259 } |
261 } | 260 } |
262 | 261 |
263 // Methods in ClassVerifier | 262 // Methods in ClassVerifier |
264 | 263 |
265 bool ClassVerifier::_verify_verbose = false; | 264 bool ClassVerifier::_verify_verbose = false; |
266 | 265 |
267 ClassVerifier::ClassVerifier( | 266 ClassVerifier::ClassVerifier( |
268 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS) | 267 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS) |
269 : _thread(THREAD), _exception_type(symbolHandle()), _message(msg), | 268 : _thread(THREAD), _exception_type(NULL), _message(msg), |
270 _message_buffer_len(msg_len), _klass(klass) { | 269 _message_buffer_len(msg_len), _klass(klass) { |
271 _this_type = VerificationType::reference_type(klass->name()); | 270 _this_type = VerificationType::reference_type(klass->name()); |
271 // Create list to hold symbols in reference area. | |
272 _symbols = new GrowableArray<Symbol*>(100, 0, NULL); | |
272 } | 273 } |
273 | 274 |
274 ClassVerifier::~ClassVerifier() { | 275 ClassVerifier::~ClassVerifier() { |
276 // Decrement the reference count for any symbols created. | |
277 for (int i = 0; i < _symbols->length(); i++) { | |
278 Symbol* s = _symbols->at(i); | |
279 s->decrement_refcount(); | |
280 } | |
275 } | 281 } |
276 | 282 |
277 VerificationType ClassVerifier::object_type() const { | 283 VerificationType ClassVerifier::object_type() const { |
278 return VerificationType::reference_type(vmSymbols::java_lang_Object()); | 284 return VerificationType::reference_type(vmSymbols::java_lang_Object()); |
279 } | 285 } |
306 _klass->external_name()); | 312 _klass->external_name()); |
307 } | 313 } |
308 } | 314 } |
309 | 315 |
310 void ClassVerifier::verify_method(methodHandle m, TRAPS) { | 316 void ClassVerifier::verify_method(methodHandle m, TRAPS) { |
311 ResourceMark rm(THREAD); | |
312 _method = m; // initialize _method | 317 _method = m; // initialize _method |
313 if (_verify_verbose) { | 318 if (_verify_verbose) { |
314 tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); | 319 tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); |
315 } | 320 } |
316 | 321 |
613 if (atype.is_null()) { | 618 if (atype.is_null()) { |
614 current_frame.push_stack( | 619 current_frame.push_stack( |
615 VerificationType::null_type(), CHECK_VERIFY(this)); | 620 VerificationType::null_type(), CHECK_VERIFY(this)); |
616 } else { | 621 } else { |
617 VerificationType component = | 622 VerificationType component = |
618 atype.get_component(CHECK_VERIFY(this)); | 623 atype.get_component(this, CHECK_VERIFY(this)); |
619 current_frame.push_stack(component, CHECK_VERIFY(this)); | 624 current_frame.push_stack(component, CHECK_VERIFY(this)); |
620 } | 625 } |
621 no_control_flow = false; break; | 626 no_control_flow = false; break; |
622 } | 627 } |
623 case Bytecodes::_istore : | 628 case Bytecodes::_istore : |
1384 VerificationType catch_type = cp_index_to_type( | 1389 VerificationType catch_type = cp_index_to_type( |
1385 catch_type_index, cp, CHECK_VERIFY(this)); | 1390 catch_type_index, cp, CHECK_VERIFY(this)); |
1386 VerificationType throwable = | 1391 VerificationType throwable = |
1387 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); | 1392 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); |
1388 bool is_subclass = throwable.is_assignable_from( | 1393 bool is_subclass = throwable.is_assignable_from( |
1389 catch_type, current_class(), CHECK_VERIFY(this)); | 1394 catch_type, this, CHECK_VERIFY(this)); |
1390 if (!is_subclass) { | 1395 if (!is_subclass) { |
1391 // 4286534: should throw VerifyError according to recent spec change | 1396 // 4286534: should throw VerifyError according to recent spec change |
1392 verify_error( | 1397 verify_error( |
1393 "Catch type is not a subclass of Throwable in handler %d", | 1398 "Catch type is not a subclass of Throwable in handler %d", |
1394 handler_pc); | 1399 handler_pc); |
1471 u2 handler_pc = exhandlers->int_at(i++); | 1476 u2 handler_pc = exhandlers->int_at(i++); |
1472 int catch_type_index = exhandlers->int_at(i++); | 1477 int catch_type_index = exhandlers->int_at(i++); |
1473 if(bci >= start_pc && bci < end_pc) { | 1478 if(bci >= start_pc && bci < end_pc) { |
1474 u1 flags = current_frame->flags(); | 1479 u1 flags = current_frame->flags(); |
1475 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } | 1480 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } |
1476 | |
1477 ResourceMark rm(THREAD); | |
1478 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); | 1481 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); |
1479 if (catch_type_index != 0) { | 1482 if (catch_type_index != 0) { |
1480 // We know that this index refers to a subclass of Throwable | 1483 // We know that this index refers to a subclass of Throwable |
1481 VerificationType catch_type = cp_index_to_type( | 1484 VerificationType catch_type = cp_index_to_type( |
1482 catch_type_index, cp, CHECK_VERIFY(this)); | 1485 catch_type_index, cp, CHECK_VERIFY(this)); |
1573 va_start(va, msg); | 1576 va_start(va, msg); |
1574 format_error_message(msg, -1, va); | 1577 format_error_message(msg, -1, va); |
1575 va_end(va); | 1578 va_end(va); |
1576 } | 1579 } |
1577 | 1580 |
1578 klassOop ClassVerifier::load_class(symbolHandle name, TRAPS) { | 1581 klassOop ClassVerifier::load_class(Symbol* name, TRAPS) { |
1579 // Get current loader and protection domain first. | 1582 // Get current loader and protection domain first. |
1580 oop loader = current_class()->class_loader(); | 1583 oop loader = current_class()->class_loader(); |
1581 oop protection_domain = current_class()->protection_domain(); | 1584 oop protection_domain = current_class()->protection_domain(); |
1582 | 1585 |
1583 return SystemDictionary::resolve_or_fail( | 1586 return SystemDictionary::resolve_or_fail( |
1585 true, CHECK_NULL); | 1588 true, CHECK_NULL); |
1586 } | 1589 } |
1587 | 1590 |
1588 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, | 1591 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, |
1589 klassOop target_class, | 1592 klassOop target_class, |
1590 symbolOop field_name, | 1593 Symbol* field_name, |
1591 symbolOop field_sig, | 1594 Symbol* field_sig, |
1592 bool is_method) { | 1595 bool is_method) { |
1593 No_Safepoint_Verifier nosafepoint; | 1596 No_Safepoint_Verifier nosafepoint; |
1594 | 1597 |
1595 // If target class isn't a super class of this class, we don't worry about this case | 1598 // If target class isn't a super class of this class, we don't worry about this case |
1596 if (!this_class->is_subclass_of(target_class)) { | 1599 if (!this_class->is_subclass_of(target_class)) { |
1734 current_frame, target, CHECK_VERIFY(this)); | 1737 current_frame, target, CHECK_VERIFY(this)); |
1735 } | 1738 } |
1736 } | 1739 } |
1737 | 1740 |
1738 bool ClassVerifier::name_in_supers( | 1741 bool ClassVerifier::name_in_supers( |
1739 symbolOop ref_name, instanceKlassHandle current) { | 1742 Symbol* ref_name, instanceKlassHandle current) { |
1740 klassOop super = current->super(); | 1743 klassOop super = current->super(); |
1741 while (super != NULL) { | 1744 while (super != NULL) { |
1742 if (super->klass_part()->name() == ref_name) { | 1745 if (super->klass_part()->name() == ref_name) { |
1743 return true; | 1746 return true; |
1744 } | 1747 } |
1753 TRAPS) { | 1756 TRAPS) { |
1754 u2 index = bcs->get_index_u2(); | 1757 u2 index = bcs->get_index_u2(); |
1755 verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); | 1758 verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); |
1756 | 1759 |
1757 // Get field name and signature | 1760 // Get field name and signature |
1758 symbolHandle field_name = symbolHandle(THREAD, cp->name_ref_at(index)); | 1761 Symbol* field_name = cp->name_ref_at(index); |
1759 symbolHandle field_sig = symbolHandle(THREAD, cp->signature_ref_at(index)); | 1762 Symbol* field_sig = cp->signature_ref_at(index); |
1760 | 1763 |
1761 if (!SignatureVerifier::is_valid_type_signature(field_sig)) { | 1764 if (!SignatureVerifier::is_valid_type_signature(field_sig)) { |
1762 class_format_error( | 1765 class_format_error( |
1763 "Invalid signature for field in class %s referenced " | 1766 "Invalid signature for field in class %s referenced " |
1764 "from constant pool index %d", _klass->external_name(), index); | 1767 "from constant pool index %d", _klass->external_name(), index); |
1821 // The JVMS 2nd edition allows field initialization before the superclass | 1824 // The JVMS 2nd edition allows field initialization before the superclass |
1822 // initializer, if the field is defined within the current class. | 1825 // initializer, if the field is defined within the current class. |
1823 fieldDescriptor fd; | 1826 fieldDescriptor fd; |
1824 if (stack_object_type == VerificationType::uninitialized_this_type() && | 1827 if (stack_object_type == VerificationType::uninitialized_this_type() && |
1825 target_class_type.equals(current_type()) && | 1828 target_class_type.equals(current_type()) && |
1826 _klass->find_local_field(field_name(), field_sig(), &fd)) { | 1829 _klass->find_local_field(field_name, field_sig, &fd)) { |
1827 stack_object_type = current_type(); | 1830 stack_object_type = current_type(); |
1828 } | 1831 } |
1829 is_assignable = target_class_type.is_assignable_from( | 1832 is_assignable = target_class_type.is_assignable_from( |
1830 stack_object_type, current_class(), CHECK_VERIFY(this)); | 1833 stack_object_type, this, CHECK_VERIFY(this)); |
1831 if (!is_assignable) { | 1834 if (!is_assignable) { |
1832 verify_error(bci, "Bad type on operand stack in putfield"); | 1835 verify_error(bci, "Bad type on operand stack in putfield"); |
1833 return; | 1836 return; |
1834 } | 1837 } |
1835 } | 1838 } |
1836 check_protected: { | 1839 check_protected: { |
1837 if (_this_type == stack_object_type) | 1840 if (_this_type == stack_object_type) |
1838 break; // stack_object_type must be assignable to _current_class_type | 1841 break; // stack_object_type must be assignable to _current_class_type |
1839 symbolHandle ref_class_name = symbolHandle(THREAD, | 1842 Symbol* ref_class_name = |
1840 cp->klass_name_at(cp->klass_ref_index_at(index))); | 1843 cp->klass_name_at(cp->klass_ref_index_at(index)); |
1841 if (!name_in_supers(ref_class_name(), current_class())) | 1844 if (!name_in_supers(ref_class_name, current_class())) |
1842 // stack_object_type must be assignable to _current_class_type since: | 1845 // stack_object_type must be assignable to _current_class_type since: |
1843 // 1. stack_object_type must be assignable to ref_class. | 1846 // 1. stack_object_type must be assignable to ref_class. |
1844 // 2. ref_class must be _current_class or a subclass of it. It can't | 1847 // 2. ref_class must be _current_class or a subclass of it. It can't |
1845 // be a superclass of it. See revised JVMS 5.4.4. | 1848 // be a superclass of it. See revised JVMS 5.4.4. |
1846 break; | 1849 break; |
1847 | 1850 |
1848 klassOop ref_class_oop = load_class(ref_class_name, CHECK); | 1851 klassOop ref_class_oop = load_class(ref_class_name, CHECK); |
1849 if (is_protected_access(current_class(), ref_class_oop, field_name(), | 1852 if (is_protected_access(current_class(), ref_class_oop, field_name, |
1850 field_sig(), false)) { | 1853 field_sig, false)) { |
1851 // It's protected access, check if stack object is assignable to | 1854 // It's protected access, check if stack object is assignable to |
1852 // current class. | 1855 // current class. |
1853 is_assignable = current_type().is_assignable_from( | 1856 is_assignable = current_type().is_assignable_from( |
1854 stack_object_type, current_class(), CHECK_VERIFY(this)); | 1857 stack_object_type, this, CHECK_VERIFY(this)); |
1855 if (!is_assignable) { | 1858 if (!is_assignable) { |
1856 verify_error(bci, "Bad access to protected data in getfield"); | 1859 verify_error(bci, "Bad access to protected data in getfield"); |
1857 return; | 1860 return; |
1858 } | 1861 } |
1859 } | 1862 } |
1909 vmSymbols::object_initializer_name(), | 1912 vmSymbols::object_initializer_name(), |
1910 cp->signature_ref_at(bcs->get_index_u2())); | 1913 cp->signature_ref_at(bcs->get_index_u2())); |
1911 instanceKlassHandle mh(THREAD, m->method_holder()); | 1914 instanceKlassHandle mh(THREAD, m->method_holder()); |
1912 if (m->is_protected() && !mh->is_same_class_package(_klass())) { | 1915 if (m->is_protected() && !mh->is_same_class_package(_klass())) { |
1913 bool assignable = current_type().is_assignable_from( | 1916 bool assignable = current_type().is_assignable_from( |
1914 objectref_type, current_class(), CHECK_VERIFY(this)); | 1917 objectref_type, this, CHECK_VERIFY(this)); |
1915 if (!assignable) { | 1918 if (!assignable) { |
1916 verify_error(bci, "Bad access to protected <init> method"); | 1919 verify_error(bci, "Bad access to protected <init> method"); |
1917 return; | 1920 return; |
1918 } | 1921 } |
1919 } | 1922 } |
1939 |1 << JVM_CONSTANT_InvokeDynamic) | 1942 |1 << JVM_CONSTANT_InvokeDynamic) |
1940 : 1 << JVM_CONSTANT_Methodref); | 1943 : 1 << JVM_CONSTANT_Methodref); |
1941 verify_cp_type(index, cp, types, CHECK_VERIFY(this)); | 1944 verify_cp_type(index, cp, types, CHECK_VERIFY(this)); |
1942 | 1945 |
1943 // Get method name and signature | 1946 // Get method name and signature |
1944 symbolHandle method_name(THREAD, cp->name_ref_at(index)); | 1947 Symbol* method_name = cp->name_ref_at(index); |
1945 symbolHandle method_sig(THREAD, cp->signature_ref_at(index)); | 1948 Symbol* method_sig = cp->signature_ref_at(index); |
1946 | 1949 |
1947 if (!SignatureVerifier::is_valid_method_signature(method_sig)) { | 1950 if (!SignatureVerifier::is_valid_method_signature(method_sig)) { |
1948 class_format_error( | 1951 class_format_error( |
1949 "Invalid method signature in class %s referenced " | 1952 "Invalid method signature in class %s referenced " |
1950 "from constant pool index %d", _klass->external_name(), index); | 1953 "from constant pool index %d", _klass->external_name(), index); |
2033 } | 2036 } |
2034 | 2037 |
2035 if (method_name->byte_at(0) == '<') { | 2038 if (method_name->byte_at(0) == '<') { |
2036 // Make sure <init> can only be invoked by invokespecial | 2039 // Make sure <init> can only be invoked by invokespecial |
2037 if (opcode != Bytecodes::_invokespecial || | 2040 if (opcode != Bytecodes::_invokespecial || |
2038 method_name() != vmSymbols::object_initializer_name()) { | 2041 method_name != vmSymbols::object_initializer_name()) { |
2039 verify_error(bci, "Illegal call to internal method"); | 2042 verify_error(bci, "Illegal call to internal method"); |
2040 return; | 2043 return; |
2041 } | 2044 } |
2042 } else if (opcode == Bytecodes::_invokespecial | 2045 } else if (opcode == Bytecodes::_invokespecial |
2043 && !ref_class_type.equals(current_type()) | 2046 && !ref_class_type.equals(current_type()) |
2044 && !ref_class_type.equals(VerificationType::reference_type( | 2047 && !ref_class_type.equals(VerificationType::reference_type( |
2045 current_class()->super()->klass_part()->name()))) { | 2048 current_class()->super()->klass_part()->name()))) { |
2046 bool subtype = ref_class_type.is_assignable_from( | 2049 bool subtype = ref_class_type.is_assignable_from( |
2047 current_type(), current_class(), CHECK_VERIFY(this)); | 2050 current_type(), this, CHECK_VERIFY(this)); |
2048 if (!subtype) { | 2051 if (!subtype) { |
2049 verify_error(bci, "Bad invokespecial instruction: " | 2052 verify_error(bci, "Bad invokespecial instruction: " |
2050 "current class isn't assignable to reference class."); | 2053 "current class isn't assignable to reference class."); |
2051 return; | 2054 return; |
2052 } | 2055 } |
2056 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); | 2059 current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this)); |
2057 } | 2060 } |
2058 // Check objectref on operand stack | 2061 // Check objectref on operand stack |
2059 if (opcode != Bytecodes::_invokestatic && | 2062 if (opcode != Bytecodes::_invokestatic && |
2060 opcode != Bytecodes::_invokedynamic) { | 2063 opcode != Bytecodes::_invokedynamic) { |
2061 if (method_name() == vmSymbols::object_initializer_name()) { // <init> method | 2064 if (method_name == vmSymbols::object_initializer_name()) { // <init> method |
2062 verify_invoke_init(bcs, ref_class_type, current_frame, | 2065 verify_invoke_init(bcs, ref_class_type, current_frame, |
2063 code_length, this_uninit, cp, CHECK_VERIFY(this)); | 2066 code_length, this_uninit, cp, CHECK_VERIFY(this)); |
2064 } else { // other methods | 2067 } else { // other methods |
2065 // Ensures that target class is assignable to method class. | 2068 // Ensures that target class is assignable to method class. |
2066 if (opcode == Bytecodes::_invokespecial) { | 2069 if (opcode == Bytecodes::_invokespecial) { |
2068 } else if (opcode == Bytecodes::_invokevirtual) { | 2071 } else if (opcode == Bytecodes::_invokevirtual) { |
2069 VerificationType stack_object_type = | 2072 VerificationType stack_object_type = |
2070 current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); | 2073 current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); |
2071 if (current_type() != stack_object_type) { | 2074 if (current_type() != stack_object_type) { |
2072 assert(cp->cache() == NULL, "not rewritten yet"); | 2075 assert(cp->cache() == NULL, "not rewritten yet"); |
2073 symbolHandle ref_class_name = symbolHandle(THREAD, | 2076 Symbol* ref_class_name = |
2074 cp->klass_name_at(cp->klass_ref_index_at(index))); | 2077 cp->klass_name_at(cp->klass_ref_index_at(index)); |
2075 // See the comments in verify_field_instructions() for | 2078 // See the comments in verify_field_instructions() for |
2076 // the rationale behind this. | 2079 // the rationale behind this. |
2077 if (name_in_supers(ref_class_name(), current_class())) { | 2080 if (name_in_supers(ref_class_name, current_class())) { |
2078 klassOop ref_class = load_class(ref_class_name, CHECK); | 2081 klassOop ref_class = load_class(ref_class_name, CHECK); |
2079 if (is_protected_access( | 2082 if (is_protected_access( |
2080 _klass, ref_class, method_name(), method_sig(), true)) { | 2083 _klass, ref_class, method_name, method_sig, true)) { |
2081 // It's protected access, check if stack object is | 2084 // It's protected access, check if stack object is |
2082 // assignable to current class. | 2085 // assignable to current class. |
2083 bool is_assignable = current_type().is_assignable_from( | 2086 bool is_assignable = current_type().is_assignable_from( |
2084 stack_object_type, current_class(), CHECK_VERIFY(this)); | 2087 stack_object_type, this, CHECK_VERIFY(this)); |
2085 if (!is_assignable) { | 2088 if (!is_assignable) { |
2086 if (ref_class_type.name() == vmSymbols::java_lang_Object() | 2089 if (ref_class_type.name() == vmSymbols::java_lang_Object() |
2087 && stack_object_type.is_array() | 2090 && stack_object_type.is_array() |
2088 && method_name() == vmSymbols::clone_name()) { | 2091 && method_name == vmSymbols::clone_name()) { |
2089 // Special case: arrays pretend to implement public Object | 2092 // Special case: arrays pretend to implement public Object |
2090 // clone(). | 2093 // clone(). |
2091 } else { | 2094 } else { |
2092 verify_error(bci, | 2095 verify_error(bci, |
2093 "Bad access to protected data in invokevirtual"); | 2096 "Bad access to protected data in invokevirtual"); |
2103 } | 2106 } |
2104 } | 2107 } |
2105 } | 2108 } |
2106 // Push the result type. | 2109 // Push the result type. |
2107 if (sig_stream.type() != T_VOID) { | 2110 if (sig_stream.type() != T_VOID) { |
2108 if (method_name() == vmSymbols::object_initializer_name()) { | 2111 if (method_name == vmSymbols::object_initializer_name()) { |
2109 // <init> method must have a void return type | 2112 // <init> method must have a void return type |
2110 verify_error(bci, "Return type must be void in <init> method"); | 2113 verify_error(bci, "Return type must be void in <init> method"); |
2111 return; | 2114 return; |
2112 } | 2115 } |
2113 VerificationType return_type[2]; | 2116 VerificationType return_type[2]; |
2128 verify_error(bci, "Illegal newarray instruction"); | 2131 verify_error(bci, "Illegal newarray instruction"); |
2129 return VerificationType::bogus_type(); | 2132 return VerificationType::bogus_type(); |
2130 } | 2133 } |
2131 | 2134 |
2132 // from_bt[index] contains the array signature which has a length of 2 | 2135 // from_bt[index] contains the array signature which has a length of 2 |
2133 symbolHandle sig = oopFactory::new_symbol_handle( | 2136 Symbol* sig = create_temporary_symbol( |
2134 from_bt[index], 2, CHECK_(VerificationType::bogus_type())); | 2137 from_bt[index], 2, CHECK_(VerificationType::bogus_type())); |
2135 return VerificationType::reference_type(sig); | 2138 return VerificationType::reference_type(sig); |
2136 } | 2139 } |
2137 | 2140 |
2138 void ClassVerifier::verify_anewarray( | 2141 void ClassVerifier::verify_anewarray( |
2141 current_frame->pop_stack( | 2144 current_frame->pop_stack( |
2142 VerificationType::integer_type(), CHECK_VERIFY(this)); | 2145 VerificationType::integer_type(), CHECK_VERIFY(this)); |
2143 | 2146 |
2144 VerificationType component_type = | 2147 VerificationType component_type = |
2145 cp_index_to_type(index, cp, CHECK_VERIFY(this)); | 2148 cp_index_to_type(index, cp, CHECK_VERIFY(this)); |
2146 ResourceMark rm(THREAD); | |
2147 int length; | 2149 int length; |
2148 char* arr_sig_str; | 2150 char* arr_sig_str; |
2149 if (component_type.is_array()) { // it's an array | 2151 if (component_type.is_array()) { // it's an array |
2150 const char* component_name = component_type.name()->as_utf8(); | 2152 const char* component_name = component_type.name()->as_utf8(); |
2151 // add one dimension to component | 2153 // add one dimension to component |
2161 arr_sig_str[0] = '['; | 2163 arr_sig_str[0] = '['; |
2162 arr_sig_str[1] = 'L'; | 2164 arr_sig_str[1] = 'L'; |
2163 strncpy(&arr_sig_str[2], component_name, length - 2); | 2165 strncpy(&arr_sig_str[2], component_name, length - 2); |
2164 arr_sig_str[length - 1] = ';'; | 2166 arr_sig_str[length - 1] = ';'; |
2165 } | 2167 } |
2166 symbolHandle arr_sig = oopFactory::new_symbol_handle( | 2168 Symbol* arr_sig = create_temporary_symbol( |
2167 arr_sig_str, length, CHECK_VERIFY(this)); | 2169 arr_sig_str, length, CHECK_VERIFY(this)); |
2168 VerificationType new_array_type = VerificationType::reference_type(arr_sig); | 2170 VerificationType new_array_type = VerificationType::reference_type(arr_sig); |
2169 current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); | 2171 current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); |
2170 } | 2172 } |
2171 | 2173 |
2254 VerificationType return_type, VerificationType type, u2 bci, TRAPS) { | 2256 VerificationType return_type, VerificationType type, u2 bci, TRAPS) { |
2255 if (return_type == VerificationType::bogus_type()) { | 2257 if (return_type == VerificationType::bogus_type()) { |
2256 verify_error(bci, "Method expects a return value"); | 2258 verify_error(bci, "Method expects a return value"); |
2257 return; | 2259 return; |
2258 } | 2260 } |
2259 bool match = return_type.is_assignable_from(type, _klass, CHECK_VERIFY(this)); | 2261 bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this)); |
2260 if (!match) { | 2262 if (!match) { |
2261 verify_error(bci, "Bad return type"); | 2263 verify_error(bci, "Bad return type"); |
2262 return; | 2264 return; |
2263 } | 2265 } |
2264 } | 2266 } |
2267 | |
2268 // The verifier creates symbols which are substrings of Symbols. | |
2269 // These are stored in the verifier until the end of verification so that | |
2270 // they can be reference counted. | |
2271 Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin, | |
2272 int end, TRAPS) { | |
2273 Symbol* sym = SymbolTable::new_symbol(s, begin, end, CHECK_NULL); | |
2274 _symbols->push(sym); | |
2275 return sym; | |
2276 } | |
2277 | |
2278 Symbol* ClassVerifier::create_temporary_symbol(const char *s, int length, TRAPS) { | |
2279 Symbol* sym = SymbolTable::new_symbol(s, length, CHECK_NULL); | |
2280 _symbols->push(sym); | |
2281 return sym; | |
2282 } |