Skip to content

Commit

Permalink
8264546: Dependencies: Context class is always an InstanceKlass
Browse files Browse the repository at this point in the history
Reviewed-by: kvn
  • Loading branch information
Vladimir Ivanov committed Apr 1, 2021
1 parent fdfa1dd commit 80681b5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 32 deletions.
5 changes: 2 additions & 3 deletions src/hotspot/share/ci/ciMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,9 +709,8 @@ ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
methodHandle target;
{
MutexLocker locker(Compile_lock);
Klass* context = actual_recv->get_Klass();
target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context,
root_m->get_Method()));
InstanceKlass* context = actual_recv->get_instanceKlass();
target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context, root_m->get_Method()));
// %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods.
}

Expand Down
38 changes: 17 additions & 21 deletions src/hotspot/share/code/dependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ oop Dependencies::DepStream::argument_oop(int i) {
return result;
}

Klass* Dependencies::DepStream::context_type() {
InstanceKlass* Dependencies::DepStream::context_type() {
assert(must_be_in_vm(), "raw oops here");

// Most dependencies have an explicit context type argument.
Expand All @@ -917,7 +917,7 @@ Klass* Dependencies::DepStream::context_type() {
if (ctxkj >= 0) {
Metadata* k = argument(ctxkj);
assert(k != NULL && k->is_klass(), "type check");
return (Klass*)k;
return InstanceKlass::cast((Klass*)k);
}
}

Expand All @@ -927,8 +927,8 @@ Klass* Dependencies::DepStream::context_type() {
int ctxkj = dep_implicit_context_arg(type());
if (ctxkj >= 0) {
Klass* k = argument_oop(ctxkj)->klass();
assert(k != NULL && k->is_klass(), "type check");
return (Klass*) k;
assert(k != NULL, "type check");
return InstanceKlass::cast(k);
}
}

Expand Down Expand Up @@ -1051,7 +1051,7 @@ class ClassHierarchyWalker {
#ifdef ASSERT
// Assert that m is inherited into ctxk, without intervening overrides.
// (May return true even if this is not true, in corner cases where we punt.)
bool check_method_context(Klass* ctxk, Method* m) {
bool check_method_context(InstanceKlass* ctxk, Method* m) {
if (m->method_holder() == ctxk)
return true; // Quick win.
if (m->is_private())
Expand Down Expand Up @@ -1169,6 +1169,7 @@ class ClassHierarchyWalker {
return in_list(k, &_participants[1]);
}
}

bool ignore_witness(Klass* witness) {
if (_record_witnesses == 0) {
return false;
Expand Down Expand Up @@ -1196,10 +1197,8 @@ class ClassHierarchyWalker {
InstanceKlass* context_type,
bool participants_hide_witnesses);
public:
Klass* find_witness_subtype(Klass* k, KlassDepChange* changes = NULL) {
Klass* find_witness_subtype(InstanceKlass* context_type, KlassDepChange* changes = NULL) {
assert(doing_subtype_search(), "must set up a subtype search");
assert(k->is_instance_klass(), "required");
InstanceKlass* context_type = InstanceKlass::cast(k);
// When looking for unexpected concrete types,
// do not look beneath expected ones.
const bool participants_hide_witnesses = true;
Expand All @@ -1211,10 +1210,8 @@ class ClassHierarchyWalker {
return find_witness_anywhere(context_type, participants_hide_witnesses);
}
}
Klass* find_witness_definer(Klass* k, KlassDepChange* changes = NULL) {
Klass* find_witness_definer(InstanceKlass* context_type, KlassDepChange* changes = NULL) {
assert(!doing_subtype_search(), "must set up a method definer search");
assert(k->is_instance_klass(), "required");
InstanceKlass* context_type = InstanceKlass::cast(k);
// When looking for unexpected concrete methods,
// look beneath expected ones, to see if there are overrides.
const bool participants_hide_witnesses = true;
Expand Down Expand Up @@ -1448,17 +1445,16 @@ Klass* Dependencies::check_evol_method(Method* m) {
// can be optimized more strongly than this, because we
// know that the checked type comes from a concrete type,
// and therefore we can disregard abstract types.)
Klass* Dependencies::check_leaf_type(Klass* ctxk) {
Klass* Dependencies::check_leaf_type(InstanceKlass* ctxk) {
assert(must_be_in_vm(), "raw oops here");
assert_locked_or_safepoint(Compile_lock);
InstanceKlass* ctx = InstanceKlass::cast(ctxk);
Klass* sub = ctx->subklass();
Klass* sub = ctxk->subklass();
if (sub != NULL) {
return sub;
} else if (ctx->nof_implementors() != 0) {
} else if (ctxk->nof_implementors() != 0) {
// if it is an interface, it must be unimplemented
// (if it is not an interface, nof_implementors is always zero)
Klass* impl = ctx->implementor();
InstanceKlass* impl = ctxk->implementor();
assert(impl != NULL, "must be set");
return impl;
} else {
Expand All @@ -1470,7 +1466,7 @@ Klass* Dependencies::check_leaf_type(Klass* ctxk) {
// The type conck itself is allowed to have have further concrete subtypes.
// This allows the compiler to narrow occurrences of ctxk by conck,
// when dealing with the types of actual instances.
Klass* Dependencies::check_abstract_with_unique_concrete_subtype(Klass* ctxk,
Klass* Dependencies::check_abstract_with_unique_concrete_subtype(InstanceKlass* ctxk,
Klass* conck,
KlassDepChange* changes) {
ClassHierarchyWalker wf(conck);
Expand All @@ -1483,7 +1479,7 @@ Klass* Dependencies::check_abstract_with_unique_concrete_subtype(Klass* ctxk,
// proper subtypes, return ctxk itself, whether it is concrete or not.
// The returned subtype is allowed to have have further concrete subtypes.
// That is, return CC1 for CX > CC1 > CC2, but NULL for CX > { CC1, CC2 }.
Klass* Dependencies::find_unique_concrete_subtype(Klass* ctxk) {
Klass* Dependencies::find_unique_concrete_subtype(InstanceKlass* ctxk) {
ClassHierarchyWalker wf(ctxk); // Ignore ctxk when walking.
wf.record_witnesses(1); // Record one other witness when walking.
Klass* wit = wf.find_witness_subtype(ctxk);
Expand Down Expand Up @@ -1511,7 +1507,7 @@ Klass* Dependencies::find_unique_concrete_subtype(Klass* ctxk) {

// If a class (or interface) has a unique concrete method uniqm, return NULL.
// Otherwise, return a class that contains an interfering method.
Klass* Dependencies::check_unique_concrete_method(Klass* ctxk,
Klass* Dependencies::check_unique_concrete_method(InstanceKlass* ctxk,
Method* uniqm,
KlassDepChange* changes) {
// Here is a missing optimization: If uniqm->is_final(),
Expand All @@ -1526,7 +1522,7 @@ Klass* Dependencies::check_unique_concrete_method(Klass* ctxk,
// (The method m must be defined or inherited in ctxk.)
// Include m itself in the set, unless it is abstract.
// If this set has exactly one element, return that element.
Method* Dependencies::find_unique_concrete_method(Klass* ctxk, Method* m) {
Method* Dependencies::find_unique_concrete_method(InstanceKlass* ctxk, Method* m) {
// Return NULL if m is marked old; must have been a redefined method.
if (m->is_old()) {
return NULL;
Expand Down Expand Up @@ -1557,7 +1553,7 @@ Method* Dependencies::find_unique_concrete_method(Klass* ctxk, Method* m) {
return fm;
}

Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes) {
Klass* Dependencies::check_has_no_finalizable_subclasses(InstanceKlass* ctxk, KlassDepChange* changes) {
Klass* search_at = ctxk;
if (changes != NULL)
search_at = changes->new_type(); // just look at the new bit
Expand Down
14 changes: 7 additions & 7 deletions src/hotspot/share/code/dependencies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,10 @@ class Dependencies: public ResourceObj {

// Checking old assertions at run-time (in the VM only):
static Klass* check_evol_method(Method* m);
static Klass* check_leaf_type(Klass* ctxk);
static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck, KlassDepChange* changes = NULL);
static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, KlassDepChange* changes = NULL);
static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL);
static Klass* check_leaf_type(InstanceKlass* ctxk);
static Klass* check_abstract_with_unique_concrete_subtype(InstanceKlass* ctxk, Klass* conck, KlassDepChange* changes = NULL);
static Klass* check_unique_concrete_method(InstanceKlass* ctxk, Method* uniqm, KlassDepChange* changes = NULL);
static Klass* check_has_no_finalizable_subclasses(InstanceKlass* ctxk, KlassDepChange* changes = NULL);
static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
// A returned Klass* is NULL if the dependency assertion is still
// valid. A non-NULL Klass* is a 'witness' to the assertion
Expand All @@ -417,8 +417,8 @@ class Dependencies: public ResourceObj {
// It is used by DepStream::spot_check_dependency_at.

// Detecting possible new assertions:
static Klass* find_unique_concrete_subtype(Klass* ctxk);
static Method* find_unique_concrete_method(Klass* ctxk, Method* m);
static Klass* find_unique_concrete_subtype(InstanceKlass* ctxk);
static Method* find_unique_concrete_method(InstanceKlass* ctxk, Method* m);

// Create the encoding which will be stored in an nmethod.
void encode_content_bytes();
Expand Down Expand Up @@ -576,7 +576,7 @@ class Dependencies: public ResourceObj {
return _xi[i]; }
Metadata* argument(int i); // => recorded_oop_at(argument_index(i))
oop argument_oop(int i); // => recorded_oop_at(argument_index(i))
Klass* context_type();
InstanceKlass* context_type();

bool is_klass_type() { return Dependencies::is_klass_type(type()); }

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject b

C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
methodHandle method (THREAD, JVMCIENV->asMethod(jvmci_method));
Klass* holder = JVMCIENV->asKlass(jvmci_type);
InstanceKlass* holder = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));
if (holder->is_interface()) {
JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
}
Expand Down

1 comment on commit 80681b5

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.