src/share/vm/oops/klassVtable.cpp

Print this page

        

*** 58,68 **** // entered as a public abstract method in C's vtable. From then on it should // 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, Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces, TRAPS) { NoSafepointVerifier nsv; // set up default result values --- 58,68 ---- // entered as a public abstract method in C's vtable. From then on it should // 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
*** 75,85 **** int len = methods->length(); for (int i = 0; i < len; i++) { assert(methods->at(i)->is_method(), "must be a Method*"); methodHandle mh(THREAD, methods->at(i)); ! if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) { vtable_length += vtableEntry::size(); // we need a new entry } } GrowableArray<Method*> new_mirandas(20); --- 75,85 ---- int len = methods->length(); for (int i = 0; i < len; i++) { assert(methods->at(i)->is_method(), "must be a Method*"); methodHandle mh(THREAD, methods->at(i)); ! if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, major_version, THREAD)) { vtable_length += vtableEntry::size(); // we need a new entry } } GrowableArray<Method*> new_mirandas(20);
*** 254,267 **** initialized = fill_in_mirandas(initialized); } // In class hierarchies where the accessibility is not increasing (i.e., going from private -> // package_private -> public/protected), the vtable might actually be smaller than our initial ! // calculation. assert(initialized <= _length, "vtable initialization failed"); for(;initialized < _length; initialized++) { ! put_method_at(NULL, initialized); } NOT_PRODUCT(verify(tty, true)); } } --- 254,272 ---- initialized = fill_in_mirandas(initialized); } // In class hierarchies where the accessibility is not increasing (i.e., going from private -> // package_private -> public/protected), the vtable might actually be smaller than our initial ! // calculation, for classfile versions for which we do not do transitive override ! // calculations. ! if (ik()->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) { ! assert(initialized == _length, "vtable initialization failed"); ! } else { assert(initialized <= _length, "vtable initialization failed"); for(;initialized < _length; initialized++) { ! table()[initialized].clear(); ! } } NOT_PRODUCT(verify(tty, true)); } }
*** 296,308 **** if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { if (log_develop_is_enabled(Trace, vtables)) { ResourceMark rm(THREAD); outputStream* logst = Log(vtables)::trace_stream(); char* sig = target_method()->name_and_sig_as_C_string(); ! logst->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", supersuperklass->internal_name(), ! _klass->internal_name(), sig, vtable_index); super_method->print_linkage_flags(logst); logst->print("overriders flags: "); target_method->print_linkage_flags(logst); logst->cr(); } --- 301,313 ---- if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { if (log_develop_is_enabled(Trace, vtables)) { ResourceMark rm(THREAD); outputStream* logst = Log(vtables)::trace_stream(); char* sig = target_method()->name_and_sig_as_C_string(); ! logst->print("transitive overriding superclass %s with %s index %d, original flags: ", supersuperklass->internal_name(), ! sig, vtable_index); super_method->print_linkage_flags(logst); logst->print("overriders flags: "); target_method->print_linkage_flags(logst); logst->cr(); }
*** 328,342 **** if (log_develop_is_enabled(Trace, vtables)) { ResourceMark rm(thread); outputStream* logst = Log(vtables)::trace_stream(); char* sig = target_method()->name_and_sig_as_C_string(); if (overrides) { ! logst->print("overriding with %s::%s index %d, original flags: ", ! target_klass->internal_name(), sig, i); } else { ! logst->print("NOT overriding with %s::%s index %d, original flags: ", ! target_klass->internal_name(), sig, i); } super_method->print_linkage_flags(logst); logst->print("overriders flags: "); target_method->print_linkage_flags(logst); logst->cr(); --- 333,347 ---- if (log_develop_is_enabled(Trace, vtables)) { ResourceMark rm(thread); outputStream* logst = Log(vtables)::trace_stream(); char* sig = target_method()->name_and_sig_as_C_string(); if (overrides) { ! logst->print("overriding with %s index %d, original flags: ", ! sig, i); } else { ! logst->print("NOT overriding with %s index %d, original flags: ", ! sig, i); } super_method->print_linkage_flags(logst); logst->print("overriders flags: "); target_method->print_linkage_flags(logst); logst->cr();
*** 564,573 **** --- 569,579 ---- bool klassVtable::needs_new_vtable_entry(methodHandle target_method, const Klass* super, Handle classloader, Symbol* classname, AccessFlags class_flags, + u2 major_version, TRAPS) { if (class_flags.is_interface()) { // Interfaces do not use vtables, except for java.lang.Object methods, // so there is no point to assigning // a vtable index to any of their local methods. If we refrain from doing this,
*** 644,655 **** return false; // else keep looking for transitive overrides } } ! // Start with lookup result and continue to search up k = superk->super(); // haven't found an override match yet; continue to look } // if the target method is public or protected it may have a matching // miranda method in the super, whose entry it should re-use. // Actually, to handle cases that javac would not generate, we need --- 650,665 ---- return false; // else keep looking for transitive overrides } } ! // Start with lookup result and continue to search up, for versions supporting transitive override ! if (major_version >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) { k = superk->super(); // haven't found an override match yet; continue to look + } else { + break; + } } // if the target method is public or protected it may have a matching // miranda method in the super, whose entry it should re-use. // Actually, to handle cases that javac would not generate, we need
*** 1498,1516 **** } #endif void vtableEntry::verify(klassVtable* vt, outputStream* st) { NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true)); assert(method() != NULL, "must have set method"); method()->verify(); // we sub_type, because it could be a miranda method ! if (!vt->klass()->is_subtype_of(method()->method_holder())) { #ifndef PRODUCT print(); #endif fatal("vtableEntry " PTR_FORMAT ": method is from subclass", p2i(this)); } } #ifndef PRODUCT void vtableEntry::print() { --- 1508,1532 ---- } #endif void vtableEntry::verify(klassVtable* vt, outputStream* st) { NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true)); + KlassHandle vtklass_h = vt->klass(); + Klass* vtklass = vtklass_h(); + if (InstanceKlass::cast(vtklass)->major_version() >= klassVtable::VTABLE_TRANSITIVE_OVERRIDE_VERSION) { assert(method() != NULL, "must have set method"); + } + if (method() != NULL) { method()->verify(); // we sub_type, because it could be a miranda method ! if (!vtklass_h->is_subtype_of(method()->method_holder())) { #ifndef PRODUCT print(); #endif fatal("vtableEntry " PTR_FORMAT ": method is from subclass", p2i(this)); } + } } #ifndef PRODUCT void vtableEntry::print() {