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 }