8264546: Dependencies: Context class is always an InstanceKlass
Reviewed-by: kvn
This commit is contained in:
parent
fdfa1dda08
commit
80681b5470
@ -709,9 +709,8 @@ ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
|
|||||||
methodHandle target;
|
methodHandle target;
|
||||||
{
|
{
|
||||||
MutexLocker locker(Compile_lock);
|
MutexLocker locker(Compile_lock);
|
||||||
Klass* context = actual_recv->get_Klass();
|
InstanceKlass* context = actual_recv->get_instanceKlass();
|
||||||
target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context,
|
target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context, root_m->get_Method()));
|
||||||
root_m->get_Method()));
|
|
||||||
// %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods.
|
// %%% 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass* Dependencies::DepStream::context_type() {
|
InstanceKlass* Dependencies::DepStream::context_type() {
|
||||||
assert(must_be_in_vm(), "raw oops here");
|
assert(must_be_in_vm(), "raw oops here");
|
||||||
|
|
||||||
// Most dependencies have an explicit context type argument.
|
// Most dependencies have an explicit context type argument.
|
||||||
@ -917,7 +917,7 @@ Klass* Dependencies::DepStream::context_type() {
|
|||||||
if (ctxkj >= 0) {
|
if (ctxkj >= 0) {
|
||||||
Metadata* k = argument(ctxkj);
|
Metadata* k = argument(ctxkj);
|
||||||
assert(k != NULL && k->is_klass(), "type check");
|
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());
|
int ctxkj = dep_implicit_context_arg(type());
|
||||||
if (ctxkj >= 0) {
|
if (ctxkj >= 0) {
|
||||||
Klass* k = argument_oop(ctxkj)->klass();
|
Klass* k = argument_oop(ctxkj)->klass();
|
||||||
assert(k != NULL && k->is_klass(), "type check");
|
assert(k != NULL, "type check");
|
||||||
return (Klass*) k;
|
return InstanceKlass::cast(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,7 +1051,7 @@ class ClassHierarchyWalker {
|
|||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// Assert that m is inherited into ctxk, without intervening overrides.
|
// 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.)
|
// (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)
|
if (m->method_holder() == ctxk)
|
||||||
return true; // Quick win.
|
return true; // Quick win.
|
||||||
if (m->is_private())
|
if (m->is_private())
|
||||||
@ -1169,6 +1169,7 @@ class ClassHierarchyWalker {
|
|||||||
return in_list(k, &_participants[1]);
|
return in_list(k, &_participants[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ignore_witness(Klass* witness) {
|
bool ignore_witness(Klass* witness) {
|
||||||
if (_record_witnesses == 0) {
|
if (_record_witnesses == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -1196,10 +1197,8 @@ class ClassHierarchyWalker {
|
|||||||
InstanceKlass* context_type,
|
InstanceKlass* context_type,
|
||||||
bool participants_hide_witnesses);
|
bool participants_hide_witnesses);
|
||||||
public:
|
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(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,
|
// When looking for unexpected concrete types,
|
||||||
// do not look beneath expected ones.
|
// do not look beneath expected ones.
|
||||||
const bool participants_hide_witnesses = true;
|
const bool participants_hide_witnesses = true;
|
||||||
@ -1211,10 +1210,8 @@ class ClassHierarchyWalker {
|
|||||||
return find_witness_anywhere(context_type, participants_hide_witnesses);
|
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(!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,
|
// When looking for unexpected concrete methods,
|
||||||
// look beneath expected ones, to see if there are overrides.
|
// look beneath expected ones, to see if there are overrides.
|
||||||
const bool participants_hide_witnesses = true;
|
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
|
// can be optimized more strongly than this, because we
|
||||||
// know that the checked type comes from a concrete type,
|
// know that the checked type comes from a concrete type,
|
||||||
// and therefore we can disregard abstract types.)
|
// 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(must_be_in_vm(), "raw oops here");
|
||||||
assert_locked_or_safepoint(Compile_lock);
|
assert_locked_or_safepoint(Compile_lock);
|
||||||
InstanceKlass* ctx = InstanceKlass::cast(ctxk);
|
Klass* sub = ctxk->subklass();
|
||||||
Klass* sub = ctx->subklass();
|
|
||||||
if (sub != NULL) {
|
if (sub != NULL) {
|
||||||
return sub;
|
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 an interface, it must be unimplemented
|
||||||
// (if it is not an interface, nof_implementors is always zero)
|
// (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");
|
assert(impl != NULL, "must be set");
|
||||||
return impl;
|
return impl;
|
||||||
} else {
|
} else {
|
||||||
@ -1470,7 +1466,7 @@ Klass* Dependencies::check_leaf_type(Klass* ctxk) {
|
|||||||
// The type conck itself is allowed to have have further concrete subtypes.
|
// The type conck itself is allowed to have have further concrete subtypes.
|
||||||
// This allows the compiler to narrow occurrences of ctxk by conck,
|
// This allows the compiler to narrow occurrences of ctxk by conck,
|
||||||
// when dealing with the types of actual instances.
|
// 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,
|
Klass* conck,
|
||||||
KlassDepChange* changes) {
|
KlassDepChange* changes) {
|
||||||
ClassHierarchyWalker wf(conck);
|
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.
|
// proper subtypes, return ctxk itself, whether it is concrete or not.
|
||||||
// The returned subtype is allowed to have have further concrete subtypes.
|
// 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 }.
|
// 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.
|
ClassHierarchyWalker wf(ctxk); // Ignore ctxk when walking.
|
||||||
wf.record_witnesses(1); // Record one other witness when walking.
|
wf.record_witnesses(1); // Record one other witness when walking.
|
||||||
Klass* wit = wf.find_witness_subtype(ctxk);
|
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.
|
// If a class (or interface) has a unique concrete method uniqm, return NULL.
|
||||||
// Otherwise, return a class that contains an interfering method.
|
// 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,
|
Method* uniqm,
|
||||||
KlassDepChange* changes) {
|
KlassDepChange* changes) {
|
||||||
// Here is a missing optimization: If uniqm->is_final(),
|
// 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.)
|
// (The method m must be defined or inherited in ctxk.)
|
||||||
// Include m itself in the set, unless it is abstract.
|
// Include m itself in the set, unless it is abstract.
|
||||||
// If this set has exactly one element, return that element.
|
// 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.
|
// Return NULL if m is marked old; must have been a redefined method.
|
||||||
if (m->is_old()) {
|
if (m->is_old()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1557,7 +1553,7 @@ Method* Dependencies::find_unique_concrete_method(Klass* ctxk, Method* m) {
|
|||||||
return fm;
|
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;
|
Klass* search_at = ctxk;
|
||||||
if (changes != NULL)
|
if (changes != NULL)
|
||||||
search_at = changes->new_type(); // just look at the new bit
|
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):
|
// Checking old assertions at run-time (in the VM only):
|
||||||
static Klass* check_evol_method(Method* m);
|
static Klass* check_evol_method(Method* m);
|
||||||
static Klass* check_leaf_type(Klass* ctxk);
|
static Klass* check_leaf_type(InstanceKlass* ctxk);
|
||||||
static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck, KlassDepChange* changes = NULL);
|
static Klass* check_abstract_with_unique_concrete_subtype(InstanceKlass* ctxk, Klass* conck, KlassDepChange* changes = NULL);
|
||||||
static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, KlassDepChange* changes = NULL);
|
static Klass* check_unique_concrete_method(InstanceKlass* ctxk, Method* uniqm, KlassDepChange* changes = NULL);
|
||||||
static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, 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);
|
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
|
// A returned Klass* is NULL if the dependency assertion is still
|
||||||
// valid. A non-NULL Klass* is a 'witness' to the assertion
|
// 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.
|
// It is used by DepStream::spot_check_dependency_at.
|
||||||
|
|
||||||
// Detecting possible new assertions:
|
// Detecting possible new assertions:
|
||||||
static Klass* find_unique_concrete_subtype(Klass* ctxk);
|
static Klass* find_unique_concrete_subtype(InstanceKlass* ctxk);
|
||||||
static Method* find_unique_concrete_method(Klass* ctxk, Method* m);
|
static Method* find_unique_concrete_method(InstanceKlass* ctxk, Method* m);
|
||||||
|
|
||||||
// Create the encoding which will be stored in an nmethod.
|
// Create the encoding which will be stored in an nmethod.
|
||||||
void encode_content_bytes();
|
void encode_content_bytes();
|
||||||
@ -576,7 +576,7 @@ class Dependencies: public ResourceObj {
|
|||||||
return _xi[i]; }
|
return _xi[i]; }
|
||||||
Metadata* argument(int i); // => recorded_oop_at(argument_index(i))
|
Metadata* argument(int i); // => recorded_oop_at(argument_index(i))
|
||||||
oop argument_oop(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()); }
|
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))
|
C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
|
||||||
methodHandle method (THREAD, JVMCIENV->asMethod(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()) {
|
if (holder->is_interface()) {
|
||||||
JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
|
JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user