comparison src/share/vm/classfile/verifier.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents fce6d7280776
children 4735d2c84362
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
151 151
152 if (TraceClassInitialization || VerboseVerification) { 152 if (TraceClassInitialization || VerboseVerification) {
153 if (HAS_PENDING_EXCEPTION) { 153 if (HAS_PENDING_EXCEPTION) {
154 tty->print("Verification for %s has", klassName); 154 tty->print("Verification for %s has", klassName);
155 tty->print_cr(" exception pending %s ", 155 tty->print_cr(" exception pending %s ",
156 instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name()); 156 InstanceKlass::cast(PENDING_EXCEPTION->klass())->external_name());
157 } else if (exception_name != NULL) { 157 } else if (exception_name != NULL) {
158 tty->print_cr("Verification for %s failed", klassName); 158 tty->print_cr("Verification for %s failed", klassName);
159 } 159 }
160 tty->print_cr("End class verification for: %s", klassName); 160 tty->print_cr("End class verification for: %s", klassName);
161 } 161 }
184 } 184 }
185 } 185 }
186 186
187 bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { 187 bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
188 Symbol* name = klass->name(); 188 Symbol* name = klass->name();
189 klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); 189 Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
190 190
191 return (should_verify_for(klass->class_loader(), should_verify_class) && 191 return (should_verify_for(klass->class_loader(), should_verify_class) &&
192 // return if the class is a bootstrapping class 192 // return if the class is a bootstrapping class
193 // or defineClass specified not to verify by default (flags override passed arg) 193 // or defineClass specified not to verify by default (flags override passed arg)
194 // We need to skip the following four for bootstraping 194 // We need to skip the following four for bootstraping
359 _type.print_on(str); 359 _type.print_on(str);
360 str->print("}"); 360 str->print("}");
361 } 361 }
362 #endif 362 #endif
363 363
364 void ErrorContext::details(outputStream* ss, methodOop method) const { 364 void ErrorContext::details(outputStream* ss, Method* method) const {
365 if (is_valid()) { 365 if (is_valid()) {
366 ss->print_cr(""); 366 ss->print_cr("");
367 ss->print_cr("Exception Details:"); 367 ss->print_cr("Exception Details:");
368 location_details(ss, method); 368 location_details(ss, method);
369 reason_details(ss); 369 reason_details(ss);
432 ss->print_cr("Unknown"); 432 ss->print_cr("Unknown");
433 } 433 }
434 ss->print_cr(""); 434 ss->print_cr("");
435 } 435 }
436 436
437 void ErrorContext::location_details(outputStream* ss, methodOop method) const { 437 void ErrorContext::location_details(outputStream* ss, Method* method) const {
438 if (_bci != -1 && method != NULL) { 438 if (_bci != -1 && method != NULL) {
439 streamIndentor si(ss); 439 streamIndentor si(ss);
440 const char* bytecode_name = "<invalid>"; 440 const char* bytecode_name = "<invalid>";
441 if (method->validate_bci_from_bcx(_bci) != -1) { 441 if (method->validate_bci_from_bcx(_bci) != -1) {
442 Bytecodes::Code code = Bytecodes::code_or_bp_at(method->bcp_from(_bci)); 442 Bytecodes::Code code = Bytecodes::code_or_bp_at(method->bcp_from(_bci));
444 bytecode_name = Bytecodes::name(code); 444 bytecode_name = Bytecodes::name(code);
445 } else { 445 } else {
446 bytecode_name = "<illegal>"; 446 bytecode_name = "<illegal>";
447 } 447 }
448 } 448 }
449 instanceKlass* ik = instanceKlass::cast(method->method_holder()); 449 InstanceKlass* ik = InstanceKlass::cast(method->method_holder());
450 ss->indent().print_cr("Location:"); 450 ss->indent().print_cr("Location:");
451 streamIndentor si2(ss); 451 streamIndentor si2(ss);
452 ss->indent().print_cr("%s.%s%s @%d: %s", 452 ss->indent().print_cr("%s.%s%s @%d: %s",
453 ik->name()->as_C_string(), method->name()->as_C_string(), 453 ik->name()->as_C_string(), method->name()->as_C_string(),
454 method->signature()->as_C_string(), _bci, bytecode_name); 454 method->signature()->as_C_string(), _bci, bytecode_name);
467 streamIndentor si2(ss); 467 streamIndentor si2(ss);
468 _expected.frame()->print_on(ss); 468 _expected.frame()->print_on(ss);
469 } 469 }
470 } 470 }
471 471
472 void ErrorContext::bytecode_details(outputStream* ss, methodOop method) const { 472 void ErrorContext::bytecode_details(outputStream* ss, Method* method) const {
473 if (method != NULL) { 473 if (method != NULL) {
474 streamIndentor si(ss); 474 streamIndentor si(ss);
475 ss->indent().print_cr("Bytecode:"); 475 ss->indent().print_cr("Bytecode:");
476 streamIndentor si2(ss); 476 streamIndentor si2(ss);
477 ss->print_data(method->code_base(), method->code_size(), false); 477 ss->print_data(method->code_base(), method->code_size(), false);
478 } 478 }
479 } 479 }
480 480
481 void ErrorContext::handler_details(outputStream* ss, methodOop method) const { 481 void ErrorContext::handler_details(outputStream* ss, Method* method) const {
482 if (method != NULL) { 482 if (method != NULL) {
483 streamIndentor si(ss); 483 streamIndentor si(ss);
484 ExceptionTable table(method); 484 ExceptionTable table(method);
485 if (table.length() > 0) { 485 if (table.length() > 0) {
486 ss->indent().print_cr("Exception Handler Table:"); 486 ss->indent().print_cr("Exception Handler Table:");
491 } 491 }
492 } 492 }
493 } 493 }
494 } 494 }
495 495
496 void ErrorContext::stackmap_details(outputStream* ss, methodOop method) const { 496 void ErrorContext::stackmap_details(outputStream* ss, Method* method) const {
497 if (method != NULL && method->has_stackmap_table()) { 497 if (method != NULL && method->has_stackmap_table()) {
498 streamIndentor si(ss); 498 streamIndentor si(ss);
499 ss->indent().print_cr("Stackmap Table:"); 499 ss->indent().print_cr("Stackmap Table:");
500 typeArrayOop data = method->stackmap_data(); 500 Array<u1>* data = method->stackmap_data();
501 stack_map_table* sm_table = 501 stack_map_table* sm_table =
502 stack_map_table::at((address)data->byte_at_addr(0)); 502 stack_map_table::at((address)data->adr_at(0));
503 stack_map_frame* sm_frame = sm_table->entries(); 503 stack_map_frame* sm_frame = sm_table->entries();
504 streamIndentor si2(ss); 504 streamIndentor si2(ss);
505 int current_offset = -1; 505 int current_offset = -1;
506 for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { 506 for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
507 ss->indent(); 507 ss->indent();
545 if (VerboseVerification) { 545 if (VerboseVerification) {
546 tty->print_cr("Verifying class %s with new format", 546 tty->print_cr("Verifying class %s with new format",
547 _klass->external_name()); 547 _klass->external_name());
548 } 548 }
549 549
550 objArrayHandle methods(THREAD, _klass->methods()); 550 Array<Method*>* methods = _klass->methods();
551 int num_methods = methods->length(); 551 int num_methods = methods->length();
552 552
553 for (int index = 0; index < num_methods; index++) { 553 for (int index = 0; index < num_methods; index++) {
554 // Check for recursive re-verification before each method. 554 // Check for recursive re-verification before each method.
555 if (was_recursively_verified()) return; 555 if (was_recursively_verified()) return;
556 556
557 methodOop m = (methodOop)methods->obj_at(index); 557 Method* m = methods->at(index);
558 if (m->is_native() || m->is_abstract()) { 558 if (m->is_native() || m->is_abstract()) {
559 // If m is native or abstract, skip it. It is checked in class file 559 // If m is native or abstract, skip it. It is checked in class file
560 // parser that methods do not override a final method. 560 // parser that methods do not override a final method.
561 continue; 561 continue;
562 } 562 }
569 _klass->external_name()); 569 _klass->external_name());
570 } 570 }
571 } 571 }
572 572
573 void ClassVerifier::verify_method(methodHandle m, TRAPS) { 573 void ClassVerifier::verify_method(methodHandle m, TRAPS) {
574 HandleMark hm(THREAD);
574 _method = m; // initialize _method 575 _method = m; // initialize _method
575 if (VerboseVerification) { 576 if (VerboseVerification) {
576 tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string()); 577 tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string());
577 } 578 }
578 579
611 // its range of code array offsets is valid. (4169817) 612 // its range of code array offsets is valid. (4169817)
612 if (m->has_localvariable_table()) { 613 if (m->has_localvariable_table()) {
613 verify_local_variable_table(code_length, code_data, CHECK_VERIFY(this)); 614 verify_local_variable_table(code_length, code_data, CHECK_VERIFY(this));
614 } 615 }
615 616
616 typeArrayHandle stackmap_data(THREAD, m->stackmap_data()); 617 Array<u1>* stackmap_data = m->stackmap_data();
617 StackMapStream stream(stackmap_data); 618 StackMapStream stream(stackmap_data);
618 StackMapReader reader(this, &stream, code_data, code_length, THREAD); 619 StackMapReader reader(this, &stream, code_data, code_length, THREAD);
619 StackMapTable stackmap_table(&reader, &current_frame, max_locals, max_stack, 620 StackMapTable stackmap_table(&reader, &current_frame, max_locals, max_stack,
620 code_data, code_length, CHECK_VERIFY(this)); 621 code_data, code_length, CHECK_VERIFY(this));
621 622
1846 u2 bci, constantPoolHandle cp, int index, TRAPS) { 1847 u2 bci, constantPoolHandle cp, int index, TRAPS) {
1847 int nconstants = cp->length(); 1848 int nconstants = cp->length();
1848 if ((index <= 0) || (index >= nconstants)) { 1849 if ((index <= 0) || (index >= nconstants)) {
1849 verify_error(ErrorContext::bad_cp_index(bci, index), 1850 verify_error(ErrorContext::bad_cp_index(bci, index),
1850 "Illegal constant pool index %d in class %s", 1851 "Illegal constant pool index %d in class %s",
1851 index, instanceKlass::cast(cp->pool_holder())->external_name()); 1852 index, InstanceKlass::cast(cp->pool_holder())->external_name());
1852 return; 1853 return;
1853 } 1854 }
1854 } 1855 }
1855 1856
1856 void ClassVerifier::verify_cp_type( 1857 void ClassVerifier::verify_cp_type(
1865 verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); 1866 verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
1866 unsigned int tag = cp->tag_at(index).value(); 1867 unsigned int tag = cp->tag_at(index).value();
1867 if ((types & (1 << tag)) == 0) { 1868 if ((types & (1 << tag)) == 0) {
1868 verify_error(ErrorContext::bad_cp_index(bci, index), 1869 verify_error(ErrorContext::bad_cp_index(bci, index),
1869 "Illegal type at constant pool entry %d in class %s", 1870 "Illegal type at constant pool entry %d in class %s",
1870 index, instanceKlass::cast(cp->pool_holder())->external_name()); 1871 index, InstanceKlass::cast(cp->pool_holder())->external_name());
1871 return; 1872 return;
1872 } 1873 }
1873 } 1874 }
1874 1875
1875 void ClassVerifier::verify_cp_class_type( 1876 void ClassVerifier::verify_cp_class_type(
1877 verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); 1878 verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
1878 constantTag tag = cp->tag_at(index); 1879 constantTag tag = cp->tag_at(index);
1879 if (!tag.is_klass() && !tag.is_unresolved_klass()) { 1880 if (!tag.is_klass() && !tag.is_unresolved_klass()) {
1880 verify_error(ErrorContext::bad_cp_index(bci, index), 1881 verify_error(ErrorContext::bad_cp_index(bci, index),
1881 "Illegal type at constant pool entry %d in class %s", 1882 "Illegal type at constant pool entry %d in class %s",
1882 index, instanceKlass::cast(cp->pool_holder())->external_name()); 1883 index, InstanceKlass::cast(cp->pool_holder())->external_name());
1883 return; 1884 return;
1884 } 1885 }
1885 } 1886 }
1886 1887
1887 void ClassVerifier::verify_error(ErrorContext ctx, const char* msg, ...) { 1888 void ClassVerifier::verify_error(ErrorContext ctx, const char* msg, ...) {
1913 ss.print(" in method %s", _method->name_and_sig_as_C_string()); 1914 ss.print(" in method %s", _method->name_and_sig_as_C_string());
1914 } 1915 }
1915 _message = ss.as_string(); 1916 _message = ss.as_string();
1916 } 1917 }
1917 1918
1918 klassOop ClassVerifier::load_class(Symbol* name, TRAPS) { 1919 Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
1919 // Get current loader and protection domain first. 1920 // Get current loader and protection domain first.
1920 oop loader = current_class()->class_loader(); 1921 oop loader = current_class()->class_loader();
1921 oop protection_domain = current_class()->protection_domain(); 1922 oop protection_domain = current_class()->protection_domain();
1922 1923
1923 return SystemDictionary::resolve_or_fail( 1924 return SystemDictionary::resolve_or_fail(
1924 name, Handle(THREAD, loader), Handle(THREAD, protection_domain), 1925 name, Handle(THREAD, loader), Handle(THREAD, protection_domain),
1925 true, CHECK_NULL); 1926 true, CHECK_NULL);
1926 } 1927 }
1927 1928
1928 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, 1929 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
1929 klassOop target_class, 1930 Klass* target_class,
1930 Symbol* field_name, 1931 Symbol* field_name,
1931 Symbol* field_sig, 1932 Symbol* field_sig,
1932 bool is_method) { 1933 bool is_method) {
1933 No_Safepoint_Verifier nosafepoint; 1934 No_Safepoint_Verifier nosafepoint;
1934 1935
1935 // If target class isn't a super class of this class, we don't worry about this case 1936 // If target class isn't a super class of this class, we don't worry about this case
1936 if (!this_class->is_subclass_of(target_class)) { 1937 if (!this_class->is_subclass_of(target_class)) {
1937 return false; 1938 return false;
1938 } 1939 }
1939 // Check if the specified method or field is protected 1940 // Check if the specified method or field is protected
1940 instanceKlass* target_instance = instanceKlass::cast(target_class); 1941 InstanceKlass* target_instance = InstanceKlass::cast(target_class);
1941 fieldDescriptor fd; 1942 fieldDescriptor fd;
1942 if (is_method) { 1943 if (is_method) {
1943 methodOop m = target_instance->uncached_lookup_method(field_name, field_sig); 1944 Method* m = target_instance->uncached_lookup_method(field_name, field_sig);
1944 if (m != NULL && m->is_protected()) { 1945 if (m != NULL && m->is_protected()) {
1945 if (!this_class->is_same_class_package(m->method_holder())) { 1946 if (!this_class->is_same_class_package(m->method_holder())) {
1946 return true; 1947 return true;
1947 } 1948 }
1948 } 1949 }
1949 } else { 1950 } else {
1950 klassOop member_klass = target_instance->find_field(field_name, field_sig, &fd); 1951 Klass* member_klass = target_instance->find_field(field_name, field_sig, &fd);
1951 if (member_klass != NULL && fd.is_protected()) { 1952 if (member_klass != NULL && fd.is_protected()) {
1952 if (!this_class->is_same_class_package(member_klass)) { 1953 if (!this_class->is_same_class_package(member_klass)) {
1953 return true; 1954 return true;
1954 } 1955 }
1955 } 1956 }
1962 constantPoolHandle cp, u2 bci, TRAPS) { 1963 constantPoolHandle cp, u2 bci, TRAPS) {
1963 verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); 1964 verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
1964 constantTag tag = cp->tag_at(index); 1965 constantTag tag = cp->tag_at(index);
1965 unsigned int types; 1966 unsigned int types;
1966 if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) { 1967 if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) {
1967 if (!tag.is_unresolved_string() && !tag.is_unresolved_klass()) { 1968 if (!tag.is_unresolved_klass()) {
1968 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float) 1969 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float)
1969 | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class) 1970 | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class)
1970 | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType); 1971 | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType);
1971 // Note: The class file parser already verified the legality of 1972 // Note: The class file parser already verified the legality of
1972 // MethodHandle and MethodType constants. 1973 // MethodHandle and MethodType constants.
1977 types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long); 1978 types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
1978 verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this)); 1979 verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this));
1979 } 1980 }
1980 if (tag.is_string() && cp->is_pseudo_string_at(index)) { 1981 if (tag.is_string() && cp->is_pseudo_string_at(index)) {
1981 current_frame->push_stack(object_type(), CHECK_VERIFY(this)); 1982 current_frame->push_stack(object_type(), CHECK_VERIFY(this));
1982 } else if (tag.is_string() || tag.is_unresolved_string()) { 1983 } else if (tag.is_string()) {
1983 current_frame->push_stack( 1984 current_frame->push_stack(
1984 VerificationType::reference_type( 1985 VerificationType::reference_type(
1985 vmSymbols::java_lang_String()), CHECK_VERIFY(this)); 1986 vmSymbols::java_lang_String()), CHECK_VERIFY(this));
1986 } else if (tag.is_klass() || tag.is_unresolved_klass()) { 1987 } else if (tag.is_klass() || tag.is_unresolved_klass()) {
1987 current_frame->push_stack( 1988 current_frame->push_stack(
2084 NOT_PRODUCT(aligned_bcp = NULL); // no longer valid at this point 2085 NOT_PRODUCT(aligned_bcp = NULL); // no longer valid at this point
2085 } 2086 }
2086 2087
2087 bool ClassVerifier::name_in_supers( 2088 bool ClassVerifier::name_in_supers(
2088 Symbol* ref_name, instanceKlassHandle current) { 2089 Symbol* ref_name, instanceKlassHandle current) {
2089 klassOop super = current->super(); 2090 Klass* super = current->super();
2090 while (super != NULL) { 2091 while (super != NULL) {
2091 if (super->klass_part()->name() == ref_name) { 2092 if (super->name() == ref_name) {
2092 return true; 2093 return true;
2093 } 2094 }
2094 super = super->klass_part()->super(); 2095 super = super->super();
2095 } 2096 }
2096 return false; 2097 return false;
2097 } 2098 }
2098 2099
2099 void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs, 2100 void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
2198 // 1. stack_object_type must be assignable to ref_class. 2199 // 1. stack_object_type must be assignable to ref_class.
2199 // 2. ref_class must be _current_class or a subclass of it. It can't 2200 // 2. ref_class must be _current_class or a subclass of it. It can't
2200 // be a superclass of it. See revised JVMS 5.4.4. 2201 // be a superclass of it. See revised JVMS 5.4.4.
2201 break; 2202 break;
2202 2203
2203 klassOop ref_class_oop = load_class(ref_class_name, CHECK); 2204 Klass* ref_class_oop = load_class(ref_class_name, CHECK);
2204 if (is_protected_access(current_class(), ref_class_oop, field_name, 2205 if (is_protected_access(current_class(), ref_class_oop, field_name,
2205 field_sig, false)) { 2206 field_sig, false)) {
2206 // It's protected access, check if stack object is assignable to 2207 // It's protected access, check if stack object is assignable to
2207 // current class. 2208 // current class.
2208 is_assignable = current_type().is_assignable_from( 2209 is_assignable = current_type().is_assignable_from(
2228 u2 bci = bcs->bci(); 2229 u2 bci = bcs->bci();
2229 VerificationType type = current_frame->pop_stack( 2230 VerificationType type = current_frame->pop_stack(
2230 VerificationType::reference_check(), CHECK_VERIFY(this)); 2231 VerificationType::reference_check(), CHECK_VERIFY(this));
2231 if (type == VerificationType::uninitialized_this_type()) { 2232 if (type == VerificationType::uninitialized_this_type()) {
2232 // The method must be an <init> method of this class or its superclass 2233 // The method must be an <init> method of this class or its superclass
2233 klassOop superk = current_class()->super(); 2234 Klass* superk = current_class()->super();
2234 if (ref_class_type.name() != current_class()->name() && 2235 if (ref_class_type.name() != current_class()->name() &&
2235 ref_class_type.name() != superk->klass_part()->name()) { 2236 ref_class_type.name() != superk->name()) {
2236 verify_error(ErrorContext::bad_type(bci, 2237 verify_error(ErrorContext::bad_type(bci,
2237 TypeOrigin::implicit(ref_class_type), 2238 TypeOrigin::implicit(ref_class_type),
2238 TypeOrigin::implicit(current_type())), 2239 TypeOrigin::implicit(current_type())),
2239 "Bad <init> method call"); 2240 "Bad <init> method call");
2240 return; 2241 return;
2268 // current class, and is in a different runtime package, and the method is 2269 // current class, and is in a different runtime package, and the method is
2269 // protected, then the objectref must be the current class or a subclass 2270 // protected, then the objectref must be the current class or a subclass
2270 // of the current class. 2271 // of the current class.
2271 VerificationType objectref_type = new_class_type; 2272 VerificationType objectref_type = new_class_type;
2272 if (name_in_supers(ref_class_type.name(), current_class())) { 2273 if (name_in_supers(ref_class_type.name(), current_class())) {
2273 klassOop ref_klass = load_class( 2274 Klass* ref_klass = load_class(
2274 ref_class_type.name(), CHECK_VERIFY(this)); 2275 ref_class_type.name(), CHECK_VERIFY(this));
2275 methodOop m = instanceKlass::cast(ref_klass)->uncached_lookup_method( 2276 Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method(
2276 vmSymbols::object_initializer_name(), 2277 vmSymbols::object_initializer_name(),
2277 cp->signature_ref_at(bcs->get_index_u2())); 2278 cp->signature_ref_at(bcs->get_index_u2()));
2278 instanceKlassHandle mh(THREAD, m->method_holder()); 2279 instanceKlassHandle mh(THREAD, m->method_holder());
2279 if (m->is_protected() && !mh->is_same_class_package(_klass())) { 2280 if (m->is_protected() && !mh->is_same_class_package(_klass())) {
2280 bool assignable = current_type().is_assignable_from( 2281 bool assignable = current_type().is_assignable_from(
2414 return; 2415 return;
2415 } 2416 }
2416 } else if (opcode == Bytecodes::_invokespecial 2417 } else if (opcode == Bytecodes::_invokespecial
2417 && !ref_class_type.equals(current_type()) 2418 && !ref_class_type.equals(current_type())
2418 && !ref_class_type.equals(VerificationType::reference_type( 2419 && !ref_class_type.equals(VerificationType::reference_type(
2419 current_class()->super()->klass_part()->name()))) { 2420 current_class()->super()->name()))) {
2420 bool subtype = ref_class_type.is_assignable_from( 2421 bool subtype = ref_class_type.is_assignable_from(
2421 current_type(), this, CHECK_VERIFY(this)); 2422 current_type(), this, CHECK_VERIFY(this));
2422 if (!subtype) { 2423 if (!subtype) {
2423 verify_error(ErrorContext::bad_code(bci), 2424 verify_error(ErrorContext::bad_code(bci),
2424 "Bad invokespecial instruction: " 2425 "Bad invokespecial instruction: "
2448 Symbol* ref_class_name = 2449 Symbol* ref_class_name =
2449 cp->klass_name_at(cp->klass_ref_index_at(index)); 2450 cp->klass_name_at(cp->klass_ref_index_at(index));
2450 // See the comments in verify_field_instructions() for 2451 // See the comments in verify_field_instructions() for
2451 // the rationale behind this. 2452 // the rationale behind this.
2452 if (name_in_supers(ref_class_name, current_class())) { 2453 if (name_in_supers(ref_class_name, current_class())) {
2453 klassOop ref_class = load_class(ref_class_name, CHECK); 2454 Klass* ref_class = load_class(ref_class_name, CHECK);
2454 if (is_protected_access( 2455 if (is_protected_access(
2455 _klass, ref_class, method_name, method_sig, true)) { 2456 _klass, ref_class, method_name, method_sig, true)) {
2456 // It's protected access, check if stack object is 2457 // It's protected access, check if stack object is
2457 // assignable to current class. 2458 // assignable to current class.
2458 bool is_assignable = current_type().is_assignable_from( 2459 bool is_assignable = current_type().is_assignable_from(