< prev index next >

src/hotspot/share/oops/klassVtable.cpp

Print this page

*** 64,74 **** // treated as any other public method in C for method over-ride purposes. void klassVtable::compute_vtable_size_and_num_mirandas( int* vtable_length_ret, int* num_new_mirandas, GrowableArray<Method*>* all_mirandas, const Klass* super, Array<Method*>* methods, AccessFlags class_flags, u2 major_version, ! Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces, TRAPS) { NoSafepointVerifier nsv; // set up default result values int vtable_length = 0; --- 64,74 ---- // treated as any other public method in C for method over-ride purposes. void klassVtable::compute_vtable_size_and_num_mirandas( int* vtable_length_ret, int* num_new_mirandas, GrowableArray<Method*>* all_mirandas, const Klass* super, Array<Method*>* methods, AccessFlags class_flags, u2 major_version, ! Handle classloader, Symbol* classname, Array<InstanceKlass*>* local_interfaces, TRAPS) { NoSafepointVerifier nsv; // set up default result values int vtable_length = 0;
*** 164,174 **** // // Revised lookup semantics introduced 1.3 (Kestrel beta) void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { // Note: Arrays can have intermediate array supers. Use java_super to skip them. ! Klass* super = _klass->java_super(); int nofNewEntries = 0; bool is_shared = _klass->is_shared(); if (!_klass->is_array_klass()) { --- 164,174 ---- // // Revised lookup semantics introduced 1.3 (Kestrel beta) void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { // Note: Arrays can have intermediate array supers. Use java_super to skip them. ! InstanceKlass* super = _klass->java_super(); int nofNewEntries = 0; bool is_shared = _klass->is_shared(); if (!_klass->is_array_klass()) {
*** 869,879 **** void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas, const Klass* super, Array<Method*>* class_methods, Array<Method*>* default_methods, ! Array<Klass*>* local_interfaces, bool is_interface) { assert((new_mirandas->length() == 0) , "current mirandas must be 0"); // iterate thru the local interfaces looking for a miranda int num_local_ifs = local_interfaces->length(); --- 869,879 ---- void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas, const Klass* super, Array<Method*>* class_methods, Array<Method*>* default_methods, ! Array<InstanceKlass*>* local_interfaces, bool is_interface) { assert((new_mirandas->length() == 0) , "current mirandas must be 0"); // iterate thru the local interfaces looking for a miranda int num_local_ifs = local_interfaces->length();
*** 881,894 **** InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i)); add_new_mirandas_to_lists(new_mirandas, all_mirandas, ik->methods(), class_methods, default_methods, super, is_interface); // iterate thru each local's super interfaces ! Array<Klass*>* super_ifs = ik->transitive_interfaces(); int num_super_ifs = super_ifs->length(); for (int j = 0; j < num_super_ifs; j++) { ! InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j)); add_new_mirandas_to_lists(new_mirandas, all_mirandas, sik->methods(), class_methods, default_methods, super, is_interface); } } --- 881,894 ---- InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i)); add_new_mirandas_to_lists(new_mirandas, all_mirandas, ik->methods(), class_methods, default_methods, super, is_interface); // iterate thru each local's super interfaces ! Array<InstanceKlass*>* super_ifs = ik->transitive_interfaces(); int num_super_ifs = super_ifs->length(); for (int j = 0; j < num_super_ifs; j++) { ! InstanceKlass *sik = super_ifs->at(j); add_new_mirandas_to_lists(new_mirandas, all_mirandas, sik->methods(), class_methods, default_methods, super, is_interface); } }
*** 1080,1090 **** // Initialization void klassItable::initialize_itable(bool checkconstraints, TRAPS) { if (_klass->is_interface()) { // This needs to go after vtable indices are assigned but // before implementors need to know the number of itable indices. ! assign_itable_indices_for_interface(_klass, THREAD); } // Cannot be setup doing bootstrapping, interfaces don't have // itables, and klass with only ones entry have empty itables if (Universe::is_bootstrapping() || --- 1080,1090 ---- // Initialization void klassItable::initialize_itable(bool checkconstraints, TRAPS) { if (_klass->is_interface()) { // This needs to go after vtable indices are assigned but // before implementors need to know the number of itable indices. ! assign_itable_indices_for_interface(InstanceKlass::cast(_klass), THREAD); } // Cannot be setup doing bootstrapping, interfaces don't have // itables, and klass with only ones entry have empty itables if (Universe::is_bootstrapping() ||
*** 1105,1115 **** for(i = 0; i < num_interfaces; i++) { itableOffsetEntry* ioe = offset_entry(i); HandleMark hm(THREAD); Klass* interf = ioe->interface_klass(); assert(interf != NULL && ioe->offset() != 0, "bad offset entry in itable"); ! initialize_itable_for_interface(ioe->offset(), interf, checkconstraints, CHECK); } } // Check that the last entry is empty itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1); --- 1105,1115 ---- for(i = 0; i < num_interfaces; i++) { itableOffsetEntry* ioe = offset_entry(i); HandleMark hm(THREAD); Klass* interf = ioe->interface_klass(); assert(interf != NULL && ioe->offset() != 0, "bad offset entry in itable"); ! initialize_itable_for_interface(ioe->offset(), InstanceKlass::cast(interf), checkconstraints, CHECK); } } // Check that the last entry is empty itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1);
*** 1126,1141 **** // e.g., CharSequence.toString (from initialize_vtable) // if (m->has_vtable_index()) return false; // NO! return true; } ! int klassItable::assign_itable_indices_for_interface(Klass* klass, TRAPS) { // an interface does not have an itable, but its methods need to be numbered ResourceMark rm(THREAD); log_develop_debug(itables)("%3d: Initializing itable indices for interface %s", ++initialize_count, klass->name()->as_C_string()); ! Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); int nof_methods = methods->length(); int ime_num = 0; for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); if (interface_method_needs_itable_index(m)) { --- 1126,1141 ---- // e.g., CharSequence.toString (from initialize_vtable) // if (m->has_vtable_index()) return false; // NO! return true; } ! int klassItable::assign_itable_indices_for_interface(InstanceKlass* klass, TRAPS) { // an interface does not have an itable, but its methods need to be numbered ResourceMark rm(THREAD); log_develop_debug(itables)("%3d: Initializing itable indices for interface %s", ++initialize_count, klass->name()->as_C_string()); ! Array<Method*>* methods = klass->methods(); int nof_methods = methods->length(); int ime_num = 0; for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); if (interface_method_needs_itable_index(m)) {
*** 1168,1181 **** } assert(ime_num == method_count_for_interface(klass), "proper sizing"); return ime_num; } ! int klassItable::method_count_for_interface(Klass* interf) { ! assert(interf->is_instance_klass(), "must be"); assert(interf->is_interface(), "must be"); ! Array<Method*>* methods = InstanceKlass::cast(interf)->methods(); int nof_methods = methods->length(); int length = 0; while (nof_methods > 0) { Method* m = methods->at(nof_methods-1); if (m->has_itable_index()) { --- 1168,1180 ---- } assert(ime_num == method_count_for_interface(klass), "proper sizing"); return ime_num; } ! int klassItable::method_count_for_interface(InstanceKlass* interf) { assert(interf->is_interface(), "must be"); ! Array<Method*>* methods = interf->methods(); int nof_methods = methods->length(); int length = 0; while (nof_methods > 0) { Method* m = methods->at(nof_methods-1); if (m->has_itable_index()) {
*** 1195,1209 **** // itable indices return length; } ! void klassItable::initialize_itable_for_interface(int method_table_offset, Klass* interf, bool checkconstraints, TRAPS) { ! Array<Method*>* methods = InstanceKlass::cast(interf)->methods(); int nof_methods = methods->length(); HandleMark hm; ! Handle interface_loader (THREAD, InstanceKlass::cast(interf)->class_loader()); int ime_count = method_count_for_interface(interf); for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); methodHandle target; --- 1194,1209 ---- // itable indices return length; } ! void klassItable::initialize_itable_for_interface(int method_table_offset, InstanceKlass* interf, bool checkconstraints, TRAPS) { ! assert(interf->is_interface(), "must be"); ! Array<Method*>* methods = interf->methods(); int nof_methods = methods->length(); HandleMark hm; ! Handle interface_loader (THREAD, interf->class_loader()); int ime_count = method_count_for_interface(interf); for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); methodHandle target;
*** 1347,1370 **** #endif // INCLUDE_JVMTI // Setup class InterfaceVisiterClosure : public StackObj { public: ! virtual void doit(Klass* intf, int method_count) = 0; }; // Visit all interfaces with at least one itable method ! void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosure *blk) { // Handle array argument for(int i = 0; i < transitive_intf->length(); i++) { ! Klass* intf = transitive_intf->at(i); assert(intf->is_interface(), "sanity check"); // Find no. of itable methods int method_count = 0; // method_count = klassItable::method_count_for_interface(intf); ! Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); if (methods->length() > 0) { for (int i = methods->length(); --i >= 0; ) { if (interface_method_needs_itable_index(methods->at(i))) { method_count++; } --- 1347,1370 ---- #endif // INCLUDE_JVMTI // Setup class InterfaceVisiterClosure : public StackObj { public: ! virtual void doit(InstanceKlass* intf, int method_count) = 0; }; // Visit all interfaces with at least one itable method ! void visit_all_interfaces(Array<InstanceKlass*>* transitive_intf, InterfaceVisiterClosure *blk) { // Handle array argument for(int i = 0; i < transitive_intf->length(); i++) { ! InstanceKlass* intf = transitive_intf->at(i); assert(intf->is_interface(), "sanity check"); // Find no. of itable methods int method_count = 0; // method_count = klassItable::method_count_for_interface(intf); ! Array<Method*>* methods = intf->methods(); if (methods->length() > 0) { for (int i = methods->length(); --i >= 0; ) { if (interface_method_needs_itable_index(methods->at(i))) { method_count++; }
*** 1372,1382 **** } // Visit all interfaces which either have any methods or can participate in receiver type check. // We do not bother to count methods in transitive interfaces, although that would allow us to skip // this step in the rare case of a zero-method interface extending another zero-method interface. ! if (method_count > 0 || InstanceKlass::cast(intf)->transitive_interfaces()->length() > 0) { blk->doit(intf, method_count); } } } --- 1372,1382 ---- } // Visit all interfaces which either have any methods or can participate in receiver type check. // We do not bother to count methods in transitive interfaces, although that would allow us to skip // this step in the rare case of a zero-method interface extending another zero-method interface. ! if (method_count > 0 || intf->transitive_interfaces()->length() > 0) { blk->doit(intf, method_count); } } }
*** 1388,1398 **** CountInterfacesClosure() { _nof_methods = 0; _nof_interfaces = 0; } int nof_methods() const { return _nof_methods; } int nof_interfaces() const { return _nof_interfaces; } ! void doit(Klass* intf, int method_count) { _nof_methods += method_count; _nof_interfaces++; } }; class SetupItableClosure : public InterfaceVisiterClosure { private: itableOffsetEntry* _offset_entry; --- 1388,1398 ---- CountInterfacesClosure() { _nof_methods = 0; _nof_interfaces = 0; } int nof_methods() const { return _nof_methods; } int nof_interfaces() const { return _nof_interfaces; } ! void doit(InstanceKlass* intf, int method_count) { _nof_methods += method_count; _nof_interfaces++; } }; class SetupItableClosure : public InterfaceVisiterClosure { private: itableOffsetEntry* _offset_entry;
*** 1405,1423 **** _method_entry = method_entry; } itableMethodEntry* method_entry() const { return _method_entry; } ! void doit(Klass* intf, int method_count) { int offset = ((address)_method_entry) - _klass_begin; _offset_entry->initialize(intf, offset); _offset_entry++; _method_entry += method_count; } }; ! int klassItable::compute_itable_size(Array<Klass*>* transitive_interfaces) { // Count no of interfaces and total number of interface methods CountInterfacesClosure cic; visit_all_interfaces(transitive_interfaces, &cic); // There's alway an extra itable entry so we can null-terminate it. --- 1405,1423 ---- _method_entry = method_entry; } itableMethodEntry* method_entry() const { return _method_entry; } ! void doit(InstanceKlass* intf, int method_count) { int offset = ((address)_method_entry) - _klass_begin; _offset_entry->initialize(intf, offset); _offset_entry++; _method_entry += method_count; } }; ! int klassItable::compute_itable_size(Array<InstanceKlass*>* transitive_interfaces) { // Count no of interfaces and total number of interface methods CountInterfacesClosure cic; visit_all_interfaces(transitive_interfaces, &cic); // There's alway an extra itable entry so we can null-terminate it.
*** 1466,1477 **** #endif } // inverse to itable_index ! Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) { ! assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); assert(intf->verify_itable_index(itable_index), ""); Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); if (itable_index < 0 || itable_index >= method_count_for_interface(intf)) return NULL; // help caller defend against bad indices --- 1466,1477 ---- #endif } // inverse to itable_index ! Method* klassItable::method_for_itable_index(InstanceKlass* intf, int itable_index) { ! assert(intf->is_interface(), "sanity check"); assert(intf->verify_itable_index(itable_index), ""); Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); if (itable_index < 0 || itable_index >= method_count_for_interface(intf)) return NULL; // help caller defend against bad indices
< prev index next >