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;
|
||||
{
|
||||
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()));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user