From nobody Mon Sep 17 00:00:00 2001 From: Alexander Astapchuk Date: Fri, 15 Dec 2006 19:35:03 +0600 Subject: [PATCH] [drlvm][EXPERIMENTAL]Optimized ld_interface_vtable. --- vm/vmcore/include/Class.h | 9 +++ vm/vmcore/src/class_support/Class.cpp | 5 ++ vm/vmcore/src/class_support/Prepare.cpp | 100 +++++++++++++++++-------------- 3 files changed, 70 insertions(+), 44 deletions(-) 5b1077c3402b31bfcd60dcd415e44c80f46684dd diff --git a/vm/vmcore/include/Class.h b/vm/vmcore/include/Class.h index 402de29..aae0a49 100644 --- a/vm/vmcore/include/Class.h +++ b/vm/vmcore/include/Class.h @@ -914,6 +914,15 @@ private: // An array of pointers to Class descriptors, one descriptor // for each corresponding entry in m_intf_table.entry[]. Class** m_intfc_table_descriptors; + + // First 3 entries of m_intfc_table_descriptors are also inlined + // here for faster access in ld_interface_vtable + Class* m_intf_2; + void* m_intf_table_2; + Class* m_intf_1; + void* m_intf_table_0; + Class* m_intf_0; + void* m_intf_table_1; // number of dimensions in array; current VM limitation is 255 // Note, that you can derive the base component type of the array diff --git a/vm/vmcore/src/class_support/Class.cpp b/vm/vmcore/src/class_support/Class.cpp index 18fe55f..9cf2afe 100644 --- a/vm/vmcore/src/class_support/Class.cpp +++ b/vm/vmcore/src/class_support/Class.cpp @@ -490,7 +490,12 @@ #endif //VM_STATS void* Class::helper_get_interface_vtable(ManagedObject* obj, Class* iid) { + if (m_intf_2 == iid) { return m_intf_table_2; } + if (m_intf_1 == iid) { return m_intf_table_1; } + if (m_intf_0 == iid) { return m_intf_table_0; } + unsigned num_intfc = m_num_intfc_table_entries; + #ifdef VM_STATS VM_Statistics::get_vm_stats().num_invokeinterface_calls++; switch(num_intfc) { diff --git a/vm/vmcore/src/class_support/Prepare.cpp b/vm/vmcore/src/class_support/Prepare.cpp index 1269cbe..1da36c0 100644 --- a/vm/vmcore/src/class_support/Prepare.cpp +++ b/vm/vmcore/src/class_support/Prepare.cpp @@ -1107,55 +1107,67 @@ NativeCodePtr prepare_gen_throw_illegal_ Intfc_Table* Class::create_and_populate_interface_table() { + if(m_num_intfc_table_entries == 0) { + return NULL; + } Intfc_Table* intfc_table; - if(m_num_intfc_table_entries != 0) { - unsigned vtable_offset = m_num_virtual_method_entries; - // shouldn't it be called vtable_index? - intfc_table = create_intfc_table(this, m_num_intfc_table_entries); - unsigned i; - for (i = 0; i < m_num_intfc_table_entries; i++) { - Class* intfc = m_intfc_table_descriptors[i]; - intfc_table->entry[i].intfc_id = intfc->get_id(); - intfc_table->entry[i].table = &m_vtable->methods[vtable_offset]; - vtable_offset += intfc->get_number_of_methods(); - if(intfc->m_static_initializer) { - // Don't count static initializers of interfaces. - vtable_offset--; - } + unsigned vtable_offset = m_num_virtual_method_entries; + // shouldn't it be called vtable_index? + intfc_table = create_intfc_table(this, m_num_intfc_table_entries); + unsigned i; + for (i = 0; i < m_num_intfc_table_entries; i++) { + Class* intfc = m_intfc_table_descriptors[i]; + intfc_table->entry[i].intfc_id = intfc->get_id(); + intfc_table->entry[i].table = &m_vtable->methods[vtable_offset]; + vtable_offset += intfc->get_number_of_methods(); + if(intfc->m_static_initializer) { + // Don't count static initializers of interfaces. + vtable_offset--; } - // Set the vtable entries to point to the code address. - unsigned meth_idx = m_num_virtual_method_entries; - for (i = 0; i < m_num_intfc_table_entries; i++) { - Class* intfc = m_intfc_table_descriptors[i]; - for(unsigned k = 0; k < intfc->get_number_of_methods(); k++) { - if (intfc->get_method(k)->is_clinit()) { - continue; - } - Method* method = m_vtable_descriptors[meth_idx]; - if(method == NULL || method->is_abstract()) { - TRACE2("classloader.prepare.ame", "Inserting Throw_AbstractMethodError stub for method\n\t" - << m_name->bytes << "." - << intfc->get_method(k)->get_name()->bytes - << intfc->get_method(k)->get_descriptor()->bytes); - m_vtable->methods[meth_idx] = - (unsigned char*)prepare_gen_throw_abstract_method_error(this, intfc->get_method(k)); - } else if(method->is_public()) { - m_vtable->methods[meth_idx] = - (unsigned char *)method->get_code_addr(); - method->add_vtable_patch(&(m_vtable->methods[meth_idx])); - } else { - TRACE2("classloader.prepare.iae", "Inserting Throw_IllegalAccessError stub for method\n\t" - << method->get_class()->get_name()->bytes << "." - << method->get_name()->bytes << method->get_descriptor()->bytes); - m_vtable->methods[meth_idx] = - (unsigned char*)prepare_gen_throw_illegal_access_error(intfc, method); - } - meth_idx++; + } + // Set the vtable entries to point to the code address. + unsigned meth_idx = m_num_virtual_method_entries; + for (i = 0; i < m_num_intfc_table_entries; i++) { + Class* intfc = m_intfc_table_descriptors[i]; + for(unsigned k = 0; k < intfc->get_number_of_methods(); k++) { + if (intfc->get_method(k)->is_clinit()) { + continue; } + Method* method = m_vtable_descriptors[meth_idx]; + if(method == NULL || method->is_abstract()) { + TRACE2("classloader.prepare.ame", "Inserting Throw_AbstractMethodError stub for method\n\t" + << m_name->bytes << "." + << intfc->get_method(k)->get_name()->bytes + << intfc->get_method(k)->get_descriptor()->bytes); + m_vtable->methods[meth_idx] = + (unsigned char*)prepare_gen_throw_abstract_method_error(this, intfc->get_method(k)); + } else if(method->is_public()) { + m_vtable->methods[meth_idx] = + (unsigned char *)method->get_code_addr(); + method->add_vtable_patch(&(m_vtable->methods[meth_idx])); + } else { + TRACE2("classloader.prepare.iae", "Inserting Throw_IllegalAccessError stub for method\n\t" + << method->get_class()->get_name()->bytes << "." + << method->get_name()->bytes << method->get_descriptor()->bytes); + m_vtable->methods[meth_idx] = + (unsigned char*)prepare_gen_throw_illegal_access_error(intfc, method); + } + meth_idx++; } - } else { - intfc_table = NULL; } + + if (m_num_intfc_table_entries>0) { + m_intf_0 = m_intfc_table_descriptors[0]; + m_intf_table_0 = intfc_table->entry[0].table; + } + if (m_num_intfc_table_entries>1) { + m_intf_1 = m_intfc_table_descriptors[1]; + m_intf_table_1 = intfc_table->entry[1].table; + } + if (m_num_intfc_table_entries>2) { + m_intf_2 = m_intfc_table_descriptors[2]; + m_intf_table_2 = intfc_table->entry[2].table; + } return intfc_table; } // Class::create_and_populate_interface_table -- 1.3.3