Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8264548: Dependencies: ClassHierarchyWalker::is_witness() cleanups #3297

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 29 additions & 19 deletions src/hotspot/share/code/dependencies.cpp
Expand Up @@ -1118,15 +1118,21 @@ class ClassHierarchyWalker {

bool is_witness(Klass* k) {
if (doing_subtype_search()) {
return Dependencies::is_concrete_klass(k);
if (Dependencies::is_concrete_klass(k)) {
return record_witness(k); // concrete subtype
} else {
return false; // not a concrete class
}
} else if (!k->is_instance_klass()) {
return false; // no methods to find in an array type
} else {
InstanceKlass* ik = InstanceKlass::cast(k);
// Search class hierarchy first, skipping private implementations
// as they never override any inherited methods
Method* m = ik->find_instance_method(_name, _signature, Klass::PrivateLookupMode::skip);
if (!Dependencies::is_concrete_method(m, ik)) {
if (Dependencies::is_concrete_method(m, ik)) {
return record_witness(k, m); // concrete method found
} else {
// Check for re-abstraction of method
if (!ik->is_interface() && m != NULL && m->is_abstract()) {
// Found a matching abstract method 'm' in the class hierarchy.
Expand All @@ -1140,23 +1146,20 @@ class ClassHierarchyWalker {
// Found a concrete subtype 'w' which does not override abstract method 'm'.
// Bail out because 'm' could be called with 'w' as receiver (leading to an
// AbstractMethodError) and thus the method we are looking for is not unique.
_found_methods[_num_participants] = m;
return true;
return record_witness(k, m);
}
}
}
// Check interface defaults also, if any exist.
Array<Method*>* default_methods = ik->default_methods();
if (default_methods == NULL)
return false;
m = ik->find_method(default_methods, _name, _signature);
if (!Dependencies::is_concrete_method(m, NULL))
return false;
if (default_methods != NULL) {
Method* dm = ik->find_method(default_methods, _name, _signature);
if (Dependencies::is_concrete_method(dm, NULL)) {
return record_witness(k, dm); // default method found
}
}
return false; // no concrete method found
}
_found_methods[_num_participants] = m;
// Note: If add_participant(k) is called,
// the method m will already be memoized for it.
return true;
}
}

Expand All @@ -1170,13 +1173,21 @@ class ClassHierarchyWalker {
}
}

bool ignore_witness(Klass* witness) {
bool record_witness(Klass* witness, Method* m) {
_found_methods[_num_participants] = m;
return record_witness(witness);
}

// It is used by is_witness() to fill up participant list (of predefined size)
// and to report the first witness candidate which doesn't fit into the list.
// Returns true when no more witnesses can be recorded.
bool record_witness(Klass* witness) {
if (_record_witnesses == 0) {
return false;
return true; // report the witness
} else {
--_record_witnesses;
add_participant(witness);
return true;
return false; // record the witness
}
}
static bool in_list(Klass* x, Klass** list) {
Expand Down Expand Up @@ -1308,8 +1319,7 @@ Klass* ClassHierarchyWalker::find_witness_in(KlassDepChange& changes,
}
}

if (is_witness(new_type) &&
!ignore_witness(new_type)) {
if (is_witness(new_type)) {
return new_type;
}

Expand Down Expand Up @@ -1364,7 +1374,7 @@ Klass* ClassHierarchyWalker::find_witness_anywhere(InstanceKlass* context_type,
if (participants_hide_witnesses) {
iter.skip_subclasses();
}
} else if (is_witness(sub) && !ignore_witness(sub)) {
} else if (is_witness(sub)) {
return sub; // found a witness
}
}
Expand Down