diff -r 1fa005fb28f5 -r 54bc75c144b0 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Wed May 28 08:09:26 2014 -0400 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu May 29 13:14:25 2014 -0700 @@ -243,7 +243,8 @@ // Look up method in klasses, including static methods // Then look up local default methods void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) { - Method* result_oop = klass->uncached_lookup_method(name, signature); + // Ignore overpasses so statics can be found during resolution + Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass); if (klass->oop_is_array()) { // Only consider klass and super klass for arrays @@ -262,6 +263,12 @@ result_oop = NULL; } + // Before considering default methods, check for an overpass in the + // current class if a method has not been found. + if (result_oop == NULL) { + result_oop = InstanceKlass::cast(klass())->find_method(name, signature); + } + if (result_oop == NULL) { Array* default_methods = InstanceKlass::cast(klass())->default_methods(); if (default_methods != NULL) { @@ -282,11 +289,11 @@ // returns first instance method // Looks up method in classes, then looks up local default methods void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { - Method* result_oop = klass->uncached_lookup_method(name, signature); + Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal); result = methodHandle(THREAD, result_oop); while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); - result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); + result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal)); } if (klass->oop_is_array()) { @@ -313,7 +320,7 @@ // First check in default method array if (!resolved_method->is_abstract() && (InstanceKlass::cast(klass())->default_methods() != NULL)) { - int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); + int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false); if (index >= 0 ) { vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); } @@ -333,7 +340,7 @@ // Specify 'true' in order to skip default methods when searching the // interfaces. Function lookup_method_in_klasses() already looked for // the method in the default methods table. - result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true)); + result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults)); } void LinkResolver::lookup_polymorphic_method(methodHandle& result, @@ -575,16 +582,7 @@ nested_exception); } - // 5. check if method is concrete - if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(resolved_klass(), - method_name, - method_signature)); - } - - // 6. access checks, access checking may be turned off when calling from within the VM. + // 5. access checks, access checking may be turned off when calling from within the VM. if (check_access) { assert(current_klass.not_null() , "current_klass should not be null"); @@ -661,16 +659,6 @@ method_signature)); } - if (nostatics && resolved_method->is_static()) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(), - resolved_method->name(), - resolved_method->signature())); - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - - if (check_access) { // JDK8 adds non-public interface methods, and accessability check requirement assert(current_klass.not_null() , "current_klass should not be null"); @@ -714,6 +702,15 @@ } } + if (nostatics && resolved_method->is_static()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), resolved_method->signature())); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + if (TraceItables && Verbose) { ResourceMark rm(THREAD); tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", @@ -1645,7 +1642,7 @@ THREAD); if (HAS_PENDING_EXCEPTION) { if (TraceMethodHandles) { - tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION); + tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); PENDING_EXCEPTION->print(); } if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {