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

8264546: Dependencies: Context class is always an InstanceKlass #3293

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter file types
Jump to
Jump to file
Failed to load files.

Always

Just for now

@@ -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.
}

@@ -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.
@@ -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);
}
}

@@ -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);
}
}

@@ -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())
@@ -1169,6 +1169,7 @@ class ClassHierarchyWalker {
return in_list(k, &_participants[1]);
}
}

bool ignore_witness(Klass* witness) {
if (_record_witnesses == 0) {
return false;
@@ -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;
@@ -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;
@@ -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 {
@@ -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);
@@ -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);
@@ -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(),
@@ -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;
@@ -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
@@ -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
@@ -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();
@@ -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()); }

@@ -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()));
}
ProTip! Use n and p to navigate between commits in a pull request.