8036805: Correct linker method lookup

Correct handling of array of primitive type qualifiers during field and method resolution.

Reviewed-by: acorn, hseigel, ahgross
This commit is contained in:
Lois Foltan 2014-05-07 19:38:22 +04:00
parent f8d533e6b6
commit edc10143cb
5 changed files with 54 additions and 20 deletions

View file

@ -246,6 +246,12 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl
// 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
result = methodHandle(THREAD, result_oop);
return;
}
// JDK 8, JVMS 5.4.3.4: Interface method resolution should
// ignore static and non-public methods of java.lang.Object,
// like clone, finalize, registerNatives.
@ -290,6 +296,11 @@ void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, Klass
result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
}
if (klass->oop_is_array()) {
// Only consider klass and super klass for arrays
return;
}
if (result.is_null()) {
Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
if (default_methods != NULL) {
@ -545,7 +556,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
// 2. lookup method in resolved klass and its super klasses
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
if (resolved_method.is_null()) { // not found in the class hierarchy
if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass
lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
@ -558,16 +569,16 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
CLEAR_PENDING_EXCEPTION;
}
}
}
if (resolved_method.is_null()) {
// 4. method lookup failed
ResourceMark rm(THREAD);
THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature),
nested_exception);
}
if (resolved_method.is_null()) {
// 4. method lookup failed
ResourceMark rm(THREAD);
THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature),
nested_exception);
}
// 5. access checks, access checking may be turned off when calling from within the VM.
@ -633,17 +644,18 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
// JDK8: also look for static methods
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
if (resolved_method.is_null()) {
if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
// lookup method in all the super-interfaces
lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
if (resolved_method.is_null()) {
// no method found
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature));
}
}
if (resolved_method.is_null()) {
// no method found
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature));
}
if (check_access) {
@ -775,7 +787,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass
}
// Resolve instance field
KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
KlassHandle sel_klass(THREAD, resolved_klass->find_field(field, sig, &fd));
// check if field exists; i.e., if a klass containing the field def has been selected
if (sel_klass.is_null()) {
ResourceMark rm(THREAD);