Skip to content

Commit

Permalink
8264731: Introduce InstanceKlass::method_at_itable_or_null()
Browse files Browse the repository at this point in the history
Reviewed-by: coleenp, dholmes
  • Loading branch information
Vladimir Ivanov committed Apr 7, 2021
1 parent 22b20f8 commit 6e2b82a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 32 deletions.
66 changes: 36 additions & 30 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3150,42 +3150,48 @@ 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());
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());
}
}

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

Klass* ik = ioe->interface_klass();
if (ik == holder) break;
}

itableMethodEntry* ime = ioe->first_method_entry(this);
Method* m = ime[index].method();
if (m == NULL) {
THROW_NULL(vmSymbols::java_lang_AbstractMethodError());
}
return m;
implements_interface = false;
return NULL; // offset entry not found
}


#if INCLUDE_JVMTI
// update default_methods for redefineclasses for methods that are
// not yet in the vtable due to concurrent subclass define and superinterface
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/oops/instanceKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,8 @@ class InstanceKlass: public Klass {

// 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);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/prims/jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down

1 comment on commit 6e2b82a

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