src/share/vm/oops/instanceKlass.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/oops/instanceKlass.cpp Fri Apr 11 08:47:30 2014
--- new/src/share/vm/oops/instanceKlass.cpp Fri Apr 11 08:47:29 2014
*** 1387,1397 ****
--- 1387,1401 ----
return -1;
}
// find_method looks up the name/signature in the local methods array
Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
! return InstanceKlass::find_method(methods(), name, signature);
! return find_method_impl(name, signature, false);
+ }
+
+ Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skip_overpass) const {
+ return InstanceKlass::find_method_impl(methods(), name, signature, skip_overpass);
}
// find_instance_method looks up the name/signature in the local methods array
// and skips over static methods
Method* InstanceKlass::find_instance_method(
*** 1404,1447 ****
--- 1408,1460 ----
}
// find_method looks up the name/signature in the local methods array
Method* InstanceKlass::find_method(
Array<Method*>* methods, Symbol* name, Symbol* signature) {
! int hit = find_method_index(methods, name, signature);
! return InstanceKlass::find_method_impl(methods, name, signature, false);
+ }
+
+ Method* InstanceKlass::find_method_impl(
+ Array<Method*>* methods, Symbol* name, Symbol* signature, bool skip_overpass) {
+ int hit = find_method_index(methods, name, signature, skip_overpass);
return hit >= 0 ? methods->at(hit): NULL;
}
// Used directly for default_methods to find the index into the
// default_vtable_indices, and indirectly by find_method
// find_method_index looks in the local methods array to return the index
! // of the matching name/signature. If, overpass methods are being ignored,
+ // the search continues to find a potential non-overpass match. This capability
+ // is important during method resolution to prefer a static method, for example,
+ // over an overpass method.
int InstanceKlass::find_method_index(
! Array<Method*>* methods, Symbol* name, Symbol* signature, bool skip_overpass) {
int hit = binary_search(methods, name);
if (hit != -1) {
Method* m = methods->at(hit);
// Do linear search to find matching signature. First, quick check
! // for common case, ignoring overpasses if requested.
! if ((m->signature() == signature) && (!skip_overpass || !m->is_overpass())) return hit;
+
// search downwards through overloaded methods
int i;
for (i = hit - 1; i >= 0; --i) {
Method* m = methods->at(i);
assert(m->is_method(), "must be method");
if (m->name() != name) break;
! if ((m->signature() == signature) && (!skip_overpass || !m->is_overpass())) return i;
}
// search upwards
for (i = hit + 1; i < methods->length(); ++i) {
Method* m = methods->at(i);
assert(m->is_method(), "must be method");
if (m->name() != name) break;
! if ((m->signature() == signature) && (!skip_overpass || !m->is_overpass())) return i;
}
// not found
#ifdef ASSERT
! int index = skip_overpass ? -1 : linear_search(methods, name, signature);
assert(index == -1, err_msg("binary search should have found entry %d", index));
#endif
}
return -1;
}
*** 1463,1482 ****
--- 1476,1494 ----
return -1;
}
// uncached_lookup_method searches both the local class methods array and all
// superclasses methods arrays, skipping any overpass methods in superclasses.
! Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
Klass* klass = const_cast<InstanceKlass*>(this);
bool dont_ignore_overpasses = true; // For the class being searched, find its overpasses.
while (klass != NULL) {
! Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, mode == skip_overpass);
! if ((method != NULL) && (dont_ignore_overpasses || !method->is_overpass())) {
return method;
}
klass = InstanceKlass::cast(klass)->super();
dont_ignore_overpasses = false; // Ignore overpass methods in all superclasses.
+ mode = skip_overpass; // Always ignore overpass methods in superclasses
}
return NULL;
}
// lookup a method in the default methods list then in all transitive interfaces
*** 1487,1515 ****
--- 1499,1527 ----
if (default_methods() != NULL) {
m = find_method(default_methods(), name, signature);
}
// Look up interfaces
if (m == NULL) {
! m = lookup_method_in_all_interfaces(name, signature, false);
! m = lookup_method_in_all_interfaces(name, signature, normal);
}
return m;
}
// lookup a method in all the interfaces that this class implements
// Do NOT return private or static methods, new in JDK8 which are not externally visible
// They should only be found in the initial InterfaceMethodRef
Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
Symbol* signature,
! bool skip_default_methods) const {
! MethodLookupMode mode) const {
Array<Klass*>* all_ifs = transitive_interfaces();
int num_ifs = all_ifs->length();
InstanceKlass *ik = NULL;
for (int i = 0; i < num_ifs; i++) {
ik = InstanceKlass::cast(all_ifs->at(i));
Method* m = ik->lookup_method(name, signature);
if (m != NULL && m->is_public() && !m->is_static() &&
! (!skip_default_methods || !m->is_default_method())) {
! ((mode != skip_defaults) || !m->is_default_method())) {
return m;
}
}
return NULL;
}
src/share/vm/oops/instanceKlass.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File