8267947: CI: Preserve consistency between has_subklass() and is_subclass_of()

Reviewed-by: thartmann, roland
This commit is contained in:
Vladimir Ivanov 2021-06-01 11:59:28 +00:00
parent 229a6e2f36
commit ffd28c4a86
2 changed files with 36 additions and 14 deletions
src/hotspot/share/ci

@ -152,16 +152,19 @@ public:
return _has_finalizer; }
bool has_subklass() {
assert(is_loaded(), "must be loaded");
if (_has_subklass == subklass_unknown ||
(_is_shared && _has_subklass == subklass_false)) {
if (flags().is_final()) {
return false;
} else {
return compute_shared_has_subklass();
}
// Ignore cached subklass_false case.
// It could be invalidated by concurrent class loading and
// can result in type paradoxes during compilation when
// a subclass is observed, but has_subklass() returns false.
if (_has_subklass == subklass_true) {
return true;
}
return _has_subklass == subklass_true;
if (flags().is_final()) {
return false;
}
return compute_shared_has_subklass();
}
jint size_helper() {
return (Klass::layout_helper_size_in_bytes(layout_helper())
>> LogHeapWordSize);

@ -75,12 +75,15 @@ bool ciKlass::is_subtype_of(ciKlass* that) {
return true;
}
VM_ENTRY_MARK;
Klass* this_klass = get_Klass();
Klass* that_klass = that->get_Klass();
bool result = this_klass->is_subtype_of(that_klass);
bool is_subtype;
GUARDED_VM_ENTRY(is_subtype = get_Klass()->is_subtype_of(that->get_Klass());)
return result;
// Ensure consistency with ciInstanceKlass::has_subklass().
assert(!that->is_instance_klass() || // array klasses are irrelevant
that->is_interface() || // has_subklass is always false for interfaces
!is_subtype || that->as_instance_klass()->has_subklass(), "inconsistent");
return is_subtype;
}
// ------------------------------------------------------------------
@ -89,7 +92,20 @@ bool ciKlass::is_subclass_of(ciKlass* that) {
assert(this->is_loaded(), "must be loaded: %s", this->name()->as_quoted_ascii());
assert(that->is_loaded(), "must be loaded: %s", that->name()->as_quoted_ascii());
GUARDED_VM_ENTRY(return get_Klass()->is_subclass_of(that->get_Klass());)
// Check to see if the klasses are identical.
if (this == that) {
return true;
}
bool is_subclass;
GUARDED_VM_ENTRY(is_subclass = get_Klass()->is_subclass_of(that->get_Klass());)
// Ensure consistency with ciInstanceKlass::has_subklass().
assert(!that->is_instance_klass() || // array klasses are irrelevant
that->is_interface() || // has_subklass is always false for interfaces
!is_subclass || that->as_instance_klass()->has_subklass(), "inconsistent");
return is_subclass;
}
// ------------------------------------------------------------------
@ -151,9 +167,11 @@ ciKlass::least_common_ancestor(ciKlass* that) {
// Many times the LCA will be either this_klass or that_klass.
// Treat these as special cases.
if (lca == that_klass) {
assert(this->is_subtype_of(that), "sanity");
return that;
}
if (this_klass == lca) {
assert(that->is_subtype_of(this), "sanity");
return this;
}
@ -161,6 +179,7 @@ ciKlass::least_common_ancestor(ciKlass* that) {
ciKlass* result =
CURRENT_THREAD_ENV->get_klass(lca);
assert(this->is_subtype_of(result) && that->is_subtype_of(result), "sanity");
return result;
}