8264731: Introduce InstanceKlass::method_at_itable_or_null()
Reviewed-by: coleenp, dholmes
This commit is contained in:
parent
22b20f8e92
commit
6e2b82a45f
@ -3150,41 +3150,47 @@ jint InstanceKlass::jvmti_class_status() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
Method* InstanceKlass::method_at_itable(Klass* holder, int index, TRAPS) {
|
||||
itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable();
|
||||
int method_table_offset_in_words = ioe->offset()/wordSize;
|
||||
int nof_interfaces = (method_table_offset_in_words - itable_offset_in_words())
|
||||
/ itableOffsetEntry::size();
|
||||
|
||||
for (int cnt = 0 ; ; cnt ++, ioe ++) {
|
||||
Method* InstanceKlass::method_at_itable(InstanceKlass* holder, int index, TRAPS) {
|
||||
bool implements_interface; // initialized by method_at_itable_or_null
|
||||
Method* m = method_at_itable_or_null(holder, index,
|
||||
implements_interface); // out parameter
|
||||
if (m != NULL) {
|
||||
assert(implements_interface, "sanity");
|
||||
return m;
|
||||
} else if (implements_interface) {
|
||||
// Throw AbstractMethodError since corresponding itable slot is empty.
|
||||
THROW_NULL(vmSymbols::java_lang_AbstractMethodError());
|
||||
} else {
|
||||
// If the interface isn't implemented by the receiver class,
|
||||
// the VM should throw IncompatibleClassChangeError.
|
||||
if (cnt >= nof_interfaces) {
|
||||
ResourceMark rm(THREAD);
|
||||
stringStream ss;
|
||||
bool same_module = (module() == holder->module());
|
||||
ss.print("Receiver class %s does not implement "
|
||||
"the interface %s defining the method to be called "
|
||||
"(%s%s%s)",
|
||||
external_name(), holder->external_name(),
|
||||
(same_module) ? joint_in_module_of_loader(holder) : class_in_module_of_loader(),
|
||||
(same_module) ? "" : "; ",
|
||||
(same_module) ? "" : holder->class_in_module_of_loader());
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string());
|
||||
}
|
||||
|
||||
Klass* ik = ioe->interface_klass();
|
||||
if (ik == holder) break;
|
||||
ResourceMark rm(THREAD);
|
||||
stringStream ss;
|
||||
bool same_module = (module() == holder->module());
|
||||
ss.print("Receiver class %s does not implement "
|
||||
"the interface %s defining the method to be called "
|
||||
"(%s%s%s)",
|
||||
external_name(), holder->external_name(),
|
||||
(same_module) ? joint_in_module_of_loader(holder) : class_in_module_of_loader(),
|
||||
(same_module) ? "" : "; ",
|
||||
(same_module) ? "" : holder->class_in_module_of_loader());
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string());
|
||||
}
|
||||
|
||||
itableMethodEntry* ime = ioe->first_method_entry(this);
|
||||
Method* m = ime[index].method();
|
||||
if (m == NULL) {
|
||||
THROW_NULL(vmSymbols::java_lang_AbstractMethodError());
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
Method* InstanceKlass::method_at_itable_or_null(InstanceKlass* holder, int index, bool& implements_interface) {
|
||||
klassItable itable(this);
|
||||
for (int i = 0; i < itable.size_offset_table(); i++) {
|
||||
itableOffsetEntry* offset_entry = itable.offset_entry(i);
|
||||
if (offset_entry->interface_klass() == holder) {
|
||||
implements_interface = true;
|
||||
itableMethodEntry* ime = offset_entry->first_method_entry(this);
|
||||
Method* m = ime[index].method();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
implements_interface = false;
|
||||
return NULL; // offset entry not found
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// update default_methods for redefineclasses for methods that are
|
||||
|
@ -1108,7 +1108,8 @@ public:
|
||||
|
||||
// Java itable
|
||||
klassItable itable() const; // return klassItable wrapper
|
||||
Method* method_at_itable(Klass* holder, int index, TRAPS);
|
||||
Method* method_at_itable(InstanceKlass* holder, int index, TRAPS);
|
||||
Method* method_at_itable_or_null(InstanceKlass* holder, int index, bool& itable_entry_found);
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
void adjust_default_methods(bool* trace_name_printed);
|
||||
|
@ -906,7 +906,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
|
||||
{
|
||||
Method* m = Method::resolve_jmethod_id(method_id);
|
||||
number_of_parameters = m->size_of_parameters();
|
||||
Klass* holder = m->method_holder();
|
||||
InstanceKlass* holder = m->method_holder();
|
||||
if (call_type != JNI_VIRTUAL) {
|
||||
selected_method = m;
|
||||
} else if (!m->has_itable_index()) {
|
||||
|
Loading…
Reference in New Issue
Block a user