Mon, 12 Aug 2019 18:30:40 +0300
8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens
duke@435 | 1 | /* |
dbuck@8716 | 2 | * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #include "precompiled.hpp" |
stefank@2314 | 26 | #include "classfile/systemDictionary.hpp" |
stefank@2314 | 27 | #include "classfile/vmSymbols.hpp" |
stefank@2314 | 28 | #include "gc_implementation/shared/markSweep.inline.hpp" |
stefank@2314 | 29 | #include "memory/gcLocker.hpp" |
jiangli@8509 | 30 | #include "memory/metaspaceShared.hpp" |
stefank@2314 | 31 | #include "memory/resourceArea.hpp" |
stefank@2314 | 32 | #include "memory/universe.inline.hpp" |
stefank@2314 | 33 | #include "oops/instanceKlass.hpp" |
stefank@2314 | 34 | #include "oops/klassVtable.hpp" |
coleenp@4037 | 35 | #include "oops/method.hpp" |
stefank@2314 | 36 | #include "oops/objArrayOop.hpp" |
stefank@2314 | 37 | #include "oops/oop.inline.hpp" |
stefank@2314 | 38 | #include "prims/jvmtiRedefineClassesTrace.hpp" |
stefank@2314 | 39 | #include "runtime/arguments.hpp" |
stefank@2314 | 40 | #include "runtime/handles.inline.hpp" |
stefank@2314 | 41 | #include "utilities/copy.hpp" |
duke@435 | 42 | |
drchase@6680 | 43 | PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
drchase@6680 | 44 | |
coleenp@4037 | 45 | inline InstanceKlass* klassVtable::ik() const { |
coleenp@4037 | 46 | Klass* k = _klass(); |
coleenp@4037 | 47 | assert(k->oop_is_instance(), "not an InstanceKlass"); |
coleenp@4037 | 48 | return (InstanceKlass*)k; |
duke@435 | 49 | } |
duke@435 | 50 | |
jiangli@8509 | 51 | bool klassVtable::is_preinitialized_vtable() { |
jiangli@8509 | 52 | return _klass->is_shared() && !MetaspaceShared::remapped_readwrite(); |
jiangli@8509 | 53 | } |
jiangli@8509 | 54 | |
duke@435 | 55 | |
duke@435 | 56 | // this function computes the vtable size (including the size needed for miranda |
drchase@5732 | 57 | // methods) and the number of miranda methods in this class. |
duke@435 | 58 | // Note on Miranda methods: Let's say there is a class C that implements |
drchase@5732 | 59 | // interface I, and none of C's superclasses implements I. |
drchase@5732 | 60 | // Let's say there is an abstract method m in I that neither C |
drchase@5732 | 61 | // nor any of its super classes implement (i.e there is no method of any access, |
drchase@5732 | 62 | // with the same name and signature as m), then m is a Miranda method which is |
duke@435 | 63 | // entered as a public abstract method in C's vtable. From then on it should |
duke@435 | 64 | // treated as any other public method in C for method over-ride purposes. |
kamg@4245 | 65 | void klassVtable::compute_vtable_size_and_num_mirandas( |
kamg@4245 | 66 | int* vtable_length_ret, int* num_new_mirandas, |
kamg@4245 | 67 | GrowableArray<Method*>* all_mirandas, Klass* super, |
kamg@4245 | 68 | Array<Method*>* methods, AccessFlags class_flags, |
kamg@4245 | 69 | Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces, |
kamg@4245 | 70 | TRAPS) { |
duke@435 | 71 | No_Safepoint_Verifier nsv; |
duke@435 | 72 | |
duke@435 | 73 | // set up default result values |
kamg@4245 | 74 | int vtable_length = 0; |
duke@435 | 75 | |
duke@435 | 76 | // start off with super's vtable length |
coleenp@4037 | 77 | InstanceKlass* sk = (InstanceKlass*)super; |
duke@435 | 78 | vtable_length = super == NULL ? 0 : sk->vtable_length(); |
duke@435 | 79 | |
duke@435 | 80 | // go thru each method in the methods table to see if it needs a new entry |
duke@435 | 81 | int len = methods->length(); |
duke@435 | 82 | for (int i = 0; i < len; i++) { |
coleenp@4037 | 83 | assert(methods->at(i)->is_method(), "must be a Method*"); |
coleenp@4037 | 84 | methodHandle mh(THREAD, methods->at(i)); |
duke@435 | 85 | |
acorn@1087 | 86 | if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) { |
duke@435 | 87 | vtable_length += vtableEntry::size(); // we need a new entry |
duke@435 | 88 | } |
duke@435 | 89 | } |
duke@435 | 90 | |
kamg@4245 | 91 | GrowableArray<Method*> new_mirandas(20); |
duke@435 | 92 | // compute the number of mirandas methods that must be added to the end |
acorn@5848 | 93 | get_mirandas(&new_mirandas, all_mirandas, super, methods, NULL, local_interfaces); |
kamg@4245 | 94 | *num_new_mirandas = new_mirandas.length(); |
kamg@4245 | 95 | |
acorn@6080 | 96 | // Interfaces do not need interface methods in their vtables |
acorn@6080 | 97 | // This includes miranda methods and during later processing, default methods |
acorn@6080 | 98 | if (!class_flags.is_interface()) { |
acorn@6080 | 99 | vtable_length += *num_new_mirandas * vtableEntry::size(); |
acorn@6080 | 100 | } |
duke@435 | 101 | |
duke@435 | 102 | if (Universe::is_bootstrapping() && vtable_length == 0) { |
duke@435 | 103 | // array classes don't have their superclass set correctly during |
duke@435 | 104 | // bootstrapping |
duke@435 | 105 | vtable_length = Universe::base_vtable_size(); |
duke@435 | 106 | } |
duke@435 | 107 | |
duke@435 | 108 | if (super == NULL && !Universe::is_bootstrapping() && |
duke@435 | 109 | vtable_length != Universe::base_vtable_size()) { |
duke@435 | 110 | // Someone is attempting to redefine java.lang.Object incorrectly. The |
duke@435 | 111 | // only way this should happen is from |
duke@435 | 112 | // SystemDictionary::resolve_from_stream(), which will detect this later |
duke@435 | 113 | // and throw a security exception. So don't assert here to let |
duke@435 | 114 | // the exception occur. |
duke@435 | 115 | vtable_length = Universe::base_vtable_size(); |
duke@435 | 116 | } |
duke@435 | 117 | assert(super != NULL || vtable_length == Universe::base_vtable_size(), |
duke@435 | 118 | "bad vtable size for class Object"); |
duke@435 | 119 | assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); |
duke@435 | 120 | assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); |
kamg@4245 | 121 | |
kamg@4245 | 122 | *vtable_length_ret = vtable_length; |
duke@435 | 123 | } |
duke@435 | 124 | |
coleenp@4037 | 125 | int klassVtable::index_of(Method* m, int len) const { |
drchase@5732 | 126 | assert(m->has_vtable_index(), "do not ask this of non-vtable methods"); |
duke@435 | 127 | return m->vtable_index(); |
duke@435 | 128 | } |
duke@435 | 129 | |
drchase@5732 | 130 | // Copy super class's vtable to the first part (prefix) of this class's vtable, |
drchase@5732 | 131 | // and return the number of entries copied. Expects that 'super' is the Java |
drchase@5732 | 132 | // super class (arrays can have "array" super classes that must be skipped). |
duke@435 | 133 | int klassVtable::initialize_from_super(KlassHandle super) { |
duke@435 | 134 | if (super.is_null()) { |
duke@435 | 135 | return 0; |
jiangli@8509 | 136 | } else if (is_preinitialized_vtable()) { |
jiangli@8509 | 137 | // A shared class' vtable is preinitialized at dump time. No need to copy |
jiangli@8509 | 138 | // methods from super class for shared class, as that was already done |
jiangli@8509 | 139 | // during archiving time. However, if Jvmti has redefined a class, |
jiangli@8509 | 140 | // copy super class's vtable in case the super class has changed. |
jiangli@8509 | 141 | return super->vtable()->length(); |
duke@435 | 142 | } else { |
duke@435 | 143 | // copy methods from superKlass |
coleenp@4037 | 144 | // can't inherit from array class, so must be InstanceKlass |
duke@435 | 145 | assert(super->oop_is_instance(), "must be instance klass"); |
coleenp@4037 | 146 | InstanceKlass* sk = (InstanceKlass*)super(); |
duke@435 | 147 | klassVtable* superVtable = sk->vtable(); |
duke@435 | 148 | assert(superVtable->length() <= _length, "vtable too short"); |
duke@435 | 149 | #ifdef ASSERT |
duke@435 | 150 | superVtable->verify(tty, true); |
duke@435 | 151 | #endif |
duke@435 | 152 | superVtable->copy_vtable_to(table()); |
duke@435 | 153 | #ifndef PRODUCT |
duke@435 | 154 | if (PrintVtables && Verbose) { |
acorn@1087 | 155 | ResourceMark rm; |
duke@435 | 156 | tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length); |
duke@435 | 157 | } |
duke@435 | 158 | #endif |
duke@435 | 159 | return superVtable->length(); |
duke@435 | 160 | } |
duke@435 | 161 | } |
duke@435 | 162 | |
drchase@5732 | 163 | // |
drchase@5732 | 164 | // Revised lookup semantics introduced 1.3 (Kestrel beta) |
duke@435 | 165 | void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { |
duke@435 | 166 | |
duke@435 | 167 | // Note: Arrays can have intermediate array supers. Use java_super to skip them. |
duke@435 | 168 | KlassHandle super (THREAD, klass()->java_super()); |
duke@435 | 169 | int nofNewEntries = 0; |
duke@435 | 170 | |
jiangli@8509 | 171 | bool is_shared = _klass->is_shared(); |
jiangli@8509 | 172 | |
duke@435 | 173 | if (PrintVtables && !klass()->oop_is_array()) { |
duke@435 | 174 | ResourceMark rm(THREAD); |
duke@435 | 175 | tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); |
duke@435 | 176 | } |
duke@435 | 177 | |
duke@435 | 178 | #ifdef ASSERT |
duke@435 | 179 | oop* end_of_obj = (oop*)_klass() + _klass()->size(); |
duke@435 | 180 | oop* end_of_vtable = (oop*)&table()[_length]; |
duke@435 | 181 | assert(end_of_vtable <= end_of_obj, "vtable extends beyond end"); |
duke@435 | 182 | #endif |
duke@435 | 183 | |
duke@435 | 184 | if (Universe::is_bootstrapping()) { |
jiangli@8509 | 185 | assert(!is_shared, "sanity"); |
duke@435 | 186 | // just clear everything |
duke@435 | 187 | for (int i = 0; i < _length; i++) table()[i].clear(); |
duke@435 | 188 | return; |
duke@435 | 189 | } |
duke@435 | 190 | |
duke@435 | 191 | int super_vtable_len = initialize_from_super(super); |
duke@435 | 192 | if (klass()->oop_is_array()) { |
duke@435 | 193 | assert(super_vtable_len == _length, "arrays shouldn't introduce new methods"); |
duke@435 | 194 | } else { |
coleenp@4037 | 195 | assert(_klass->oop_is_instance(), "must be InstanceKlass"); |
duke@435 | 196 | |
coleenp@4037 | 197 | Array<Method*>* methods = ik()->methods(); |
coleenp@4037 | 198 | int len = methods->length(); |
duke@435 | 199 | int initialized = super_vtable_len; |
duke@435 | 200 | |
drchase@5732 | 201 | // Check each of this class's methods against super; |
drchase@5732 | 202 | // if override, replace in copy of super vtable, otherwise append to end |
duke@435 | 203 | for (int i = 0; i < len; i++) { |
drchase@5732 | 204 | // update_inherited_vtable can stop for gc - ensure using handles |
duke@435 | 205 | HandleMark hm(THREAD); |
coleenp@4037 | 206 | assert(methods->at(i)->is_method(), "must be a Method*"); |
coleenp@4037 | 207 | methodHandle mh(THREAD, methods->at(i)); |
duke@435 | 208 | |
acorn@5848 | 209 | bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, -1, checkconstraints, CHECK); |
duke@435 | 210 | |
duke@435 | 211 | if (needs_new_entry) { |
duke@435 | 212 | put_method_at(mh(), initialized); |
duke@435 | 213 | mh()->set_vtable_index(initialized); // set primary vtable index |
duke@435 | 214 | initialized++; |
duke@435 | 215 | } |
duke@435 | 216 | } |
duke@435 | 217 | |
acorn@5848 | 218 | // update vtable with default_methods |
acorn@5848 | 219 | Array<Method*>* default_methods = ik()->default_methods(); |
acorn@5848 | 220 | if (default_methods != NULL) { |
acorn@5848 | 221 | len = default_methods->length(); |
acorn@5848 | 222 | if (len > 0) { |
acorn@5848 | 223 | Array<int>* def_vtable_indices = NULL; |
acorn@5848 | 224 | if ((def_vtable_indices = ik()->default_vtable_indices()) == NULL) { |
jiangli@8509 | 225 | assert(!is_shared, "shared class def_vtable_indices does not exist"); |
acorn@5848 | 226 | def_vtable_indices = ik()->create_new_default_vtable_indices(len, CHECK); |
acorn@5848 | 227 | } else { |
acorn@5848 | 228 | assert(def_vtable_indices->length() == len, "reinit vtable len?"); |
acorn@5848 | 229 | } |
acorn@5848 | 230 | for (int i = 0; i < len; i++) { |
acorn@5848 | 231 | HandleMark hm(THREAD); |
acorn@5848 | 232 | assert(default_methods->at(i)->is_method(), "must be a Method*"); |
acorn@5848 | 233 | methodHandle mh(THREAD, default_methods->at(i)); |
acorn@5848 | 234 | |
acorn@5848 | 235 | bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, i, checkconstraints, CHECK); |
acorn@5848 | 236 | |
acorn@5848 | 237 | // needs new entry |
acorn@5848 | 238 | if (needs_new_entry) { |
acorn@5848 | 239 | put_method_at(mh(), initialized); |
jiangli@8509 | 240 | if (is_preinitialized_vtable()) { |
jiangli@8509 | 241 | // At runtime initialize_vtable is rerun for a shared class |
jiangli@8509 | 242 | // (loaded by the non-boot loader) as part of link_class_impl(). |
jiangli@8509 | 243 | // The dumptime vtable index should be the same as the runtime index. |
jiangli@8509 | 244 | assert(def_vtable_indices->at(i) == initialized, |
jiangli@8509 | 245 | "dump time vtable index is different from runtime index"); |
jiangli@8509 | 246 | } else { |
jiangli@8509 | 247 | def_vtable_indices->at_put(i, initialized); //set vtable index |
jiangli@8509 | 248 | } |
acorn@5848 | 249 | initialized++; |
acorn@5848 | 250 | } |
acorn@5848 | 251 | } |
acorn@5848 | 252 | } |
acorn@5848 | 253 | } |
acorn@5848 | 254 | |
acorn@5848 | 255 | // add miranda methods; it will also return the updated initialized |
acorn@6080 | 256 | // Interfaces do not need interface methods in their vtables |
acorn@6080 | 257 | // This includes miranda methods and during later processing, default methods |
acorn@6080 | 258 | if (!ik()->is_interface()) { |
acorn@6080 | 259 | initialized = fill_in_mirandas(initialized); |
acorn@6080 | 260 | } |
duke@435 | 261 | |
acorn@1087 | 262 | // In class hierarchies where the accessibility is not increasing (i.e., going from private -> |
drchase@5732 | 263 | // package_private -> public/protected), the vtable might actually be smaller than our initial |
duke@435 | 264 | // calculation. |
duke@435 | 265 | assert(initialized <= _length, "vtable initialization failed"); |
duke@435 | 266 | for(;initialized < _length; initialized++) { |
duke@435 | 267 | put_method_at(NULL, initialized); |
duke@435 | 268 | } |
duke@435 | 269 | NOT_PRODUCT(verify(tty, true)); |
duke@435 | 270 | } |
duke@435 | 271 | } |
duke@435 | 272 | |
acorn@1087 | 273 | // Called for cases where a method does not override its superclass' vtable entry |
acorn@1087 | 274 | // For bytecodes not produced by javac together it is possible that a method does not override |
acorn@1087 | 275 | // the superclass's method, but might indirectly override a super-super class's vtable entry |
acorn@1087 | 276 | // If none found, return a null superk, else return the superk of the method this does override |
hseigel@6759 | 277 | // For public and protected methods: if they override a superclass, they will |
hseigel@6759 | 278 | // also be overridden themselves appropriately. |
hseigel@6759 | 279 | // Private methods do not override and are not overridden. |
hseigel@6759 | 280 | // Package Private methods are trickier: |
hseigel@6759 | 281 | // e.g. P1.A, pub m |
hseigel@6759 | 282 | // P2.B extends A, package private m |
hseigel@6759 | 283 | // P1.C extends B, public m |
hseigel@6759 | 284 | // P1.C.m needs to override P1.A.m and can not override P2.B.m |
hseigel@6759 | 285 | // Therefore: all package private methods need their own vtable entries for |
hseigel@6759 | 286 | // them to be the root of an inheritance overriding decision |
hseigel@6759 | 287 | // Package private methods may also override other vtable entries |
coleenp@4037 | 288 | InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, |
coleenp@2497 | 289 | int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { |
coleenp@4037 | 290 | InstanceKlass* superk = initialsuper; |
acorn@1087 | 291 | while (superk != NULL && superk->super() != NULL) { |
coleenp@4037 | 292 | InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super()); |
acorn@1087 | 293 | klassVtable* ssVtable = supersuperklass->vtable(); |
acorn@1087 | 294 | if (vtable_index < ssVtable->length()) { |
coleenp@4037 | 295 | Method* super_method = ssVtable->method_at(vtable_index); |
acorn@1087 | 296 | #ifndef PRODUCT |
coleenp@2497 | 297 | Symbol* name= target_method()->name(); |
coleenp@2497 | 298 | Symbol* signature = target_method()->signature(); |
coleenp@2497 | 299 | assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); |
acorn@1087 | 300 | #endif |
acorn@1087 | 301 | if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { |
acorn@1087 | 302 | #ifndef PRODUCT |
acorn@1087 | 303 | if (PrintVtables && Verbose) { |
acorn@1087 | 304 | ResourceMark rm(THREAD); |
acorn@5848 | 305 | char* sig = target_method()->name_and_sig_as_C_string(); |
acorn@1087 | 306 | tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", |
acorn@1087 | 307 | supersuperklass->internal_name(), |
acorn@5848 | 308 | _klass->internal_name(), sig, vtable_index); |
acorn@1087 | 309 | super_method->access_flags().print_on(tty); |
acorn@5848 | 310 | if (super_method->is_default_method()) { |
acorn@6080 | 311 | tty->print("default "); |
acorn@5848 | 312 | } |
acorn@1087 | 313 | tty->print("overriders flags: "); |
acorn@1087 | 314 | target_method->access_flags().print_on(tty); |
acorn@5848 | 315 | if (target_method->is_default_method()) { |
acorn@6080 | 316 | tty->print("default "); |
acorn@5848 | 317 | } |
acorn@1087 | 318 | } |
acorn@1087 | 319 | #endif /*PRODUCT*/ |
acorn@1087 | 320 | break; // return found superk |
acorn@1087 | 321 | } |
acorn@1087 | 322 | } else { |
acorn@1087 | 323 | // super class has no vtable entry here, stop transitive search |
coleenp@4037 | 324 | superk = (InstanceKlass*)NULL; |
acorn@1087 | 325 | break; |
acorn@1087 | 326 | } |
acorn@1087 | 327 | // if no override found yet, continue to search up |
coleenp@4037 | 328 | superk = InstanceKlass::cast(superk->super()); |
acorn@1087 | 329 | } |
duke@435 | 330 | |
acorn@1087 | 331 | return superk; |
duke@435 | 332 | } |
duke@435 | 333 | |
duke@435 | 334 | // Update child's copy of super vtable for overrides |
drchase@5732 | 335 | // OR return true if a new vtable entry is required. |
coleenp@4037 | 336 | // Only called for InstanceKlass's, i.e. not for arrays |
duke@435 | 337 | // If that changed, could not use _klass as handle for klass |
acorn@5848 | 338 | bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, |
acorn@5848 | 339 | int super_vtable_len, int default_index, |
acorn@5848 | 340 | bool checkconstraints, TRAPS) { |
duke@435 | 341 | ResourceMark rm; |
duke@435 | 342 | bool allocate_new = true; |
coleenp@4037 | 343 | assert(klass->oop_is_instance(), "must be InstanceKlass"); |
duke@435 | 344 | |
acorn@5848 | 345 | Array<int>* def_vtable_indices = NULL; |
acorn@5848 | 346 | bool is_default = false; |
acorn@5848 | 347 | // default methods are concrete methods in superinterfaces which are added to the vtable |
acorn@5848 | 348 | // with their real method_holder |
acorn@5848 | 349 | // Since vtable and itable indices share the same storage, don't touch |
acorn@5848 | 350 | // the default method's real vtable/itable index |
acorn@5848 | 351 | // default_vtable_indices stores the vtable value relative to this inheritor |
acorn@5848 | 352 | if (default_index >= 0 ) { |
acorn@5848 | 353 | is_default = true; |
acorn@5848 | 354 | def_vtable_indices = klass->default_vtable_indices(); |
acorn@5848 | 355 | assert(def_vtable_indices != NULL, "def vtable alloc?"); |
acorn@5848 | 356 | assert(default_index <= def_vtable_indices->length(), "def vtable len?"); |
acorn@5848 | 357 | } else { |
acorn@5848 | 358 | assert(klass == target_method()->method_holder(), "caller resp."); |
acorn@5848 | 359 | // Initialize the method's vtable index to "nonvirtual". |
acorn@5848 | 360 | // If we allocate a vtable entry, we will update it to a non-negative number. |
acorn@5848 | 361 | target_method()->set_vtable_index(Method::nonvirtual_vtable_index); |
acorn@5848 | 362 | } |
duke@435 | 363 | |
duke@435 | 364 | // Static and <init> methods are never in |
duke@435 | 365 | if (target_method()->is_static() || target_method()->name() == vmSymbols::object_initializer_name()) { |
duke@435 | 366 | return false; |
duke@435 | 367 | } |
duke@435 | 368 | |
drchase@5732 | 369 | if (target_method->is_final_method(klass->access_flags())) { |
duke@435 | 370 | // a final method never needs a new entry; final methods can be statically |
duke@435 | 371 | // resolved and they have to be present in the vtable only if they override |
duke@435 | 372 | // a super's method, in which case they re-use its entry |
duke@435 | 373 | allocate_new = false; |
drchase@5732 | 374 | } else if (klass->is_interface()) { |
drchase@5732 | 375 | allocate_new = false; // see note below in needs_new_vtable_entry |
drchase@5732 | 376 | // An interface never allocates new vtable slots, only inherits old ones. |
drchase@5732 | 377 | // This method will either be assigned its own itable index later, |
drchase@5732 | 378 | // or be assigned an inherited vtable index in the loop below. |
acorn@6080 | 379 | // default methods inherited by classes store their vtable indices |
acorn@6080 | 380 | // in the inheritor's default_vtable_indices |
acorn@6080 | 381 | // default methods inherited by interfaces may already have a |
acorn@6080 | 382 | // valid itable index, if so, don't change it |
acorn@6080 | 383 | // overpass methods in an interface will be assigned an itable index later |
acorn@6080 | 384 | // by an inheriting class |
acorn@6080 | 385 | if (!is_default || !target_method()->has_itable_index()) { |
acorn@6080 | 386 | target_method()->set_vtable_index(Method::pending_itable_index); |
acorn@6080 | 387 | } |
duke@435 | 388 | } |
duke@435 | 389 | |
duke@435 | 390 | // we need a new entry if there is no superclass |
jiangli@8509 | 391 | Klass* super = klass->super(); |
jiangli@8509 | 392 | if (super == NULL) { |
duke@435 | 393 | return allocate_new; |
duke@435 | 394 | } |
duke@435 | 395 | |
acorn@5786 | 396 | // private methods in classes always have a new entry in the vtable |
acorn@1087 | 397 | // specification interpretation since classic has |
acorn@1087 | 398 | // private methods not overriding |
acorn@5786 | 399 | // JDK8 adds private methods in interfaces which require invokespecial |
duke@435 | 400 | if (target_method()->is_private()) { |
duke@435 | 401 | return allocate_new; |
duke@435 | 402 | } |
duke@435 | 403 | |
duke@435 | 404 | // search through the vtable and update overridden entries |
duke@435 | 405 | // Since check_signature_loaders acquires SystemDictionary_lock |
acorn@1087 | 406 | // which can block for gc, once we are in this loop, use handles |
acorn@1087 | 407 | // For classfiles built with >= jdk7, we now look for transitive overrides |
duke@435 | 408 | |
coleenp@2497 | 409 | Symbol* name = target_method()->name(); |
coleenp@2497 | 410 | Symbol* signature = target_method()->signature(); |
acorn@5848 | 411 | |
acorn@5848 | 412 | KlassHandle target_klass(THREAD, target_method()->method_holder()); |
acorn@5848 | 413 | if (target_klass == NULL) { |
acorn@5848 | 414 | target_klass = _klass; |
acorn@5848 | 415 | } |
acorn@5848 | 416 | |
acorn@5848 | 417 | Handle target_loader(THREAD, target_klass->class_loader()); |
acorn@5848 | 418 | |
acorn@5848 | 419 | Symbol* target_classname = target_klass->name(); |
duke@435 | 420 | for(int i = 0; i < super_vtable_len; i++) { |
jiangli@8509 | 421 | Method* super_method; |
jiangli@8509 | 422 | if (is_preinitialized_vtable()) { |
jiangli@8509 | 423 | // If this is a shared class, the vtable is already in the final state (fully |
jiangli@8509 | 424 | // initialized). Need to look at the super's vtable. |
jiangli@8509 | 425 | klassVtable* superVtable = super->vtable(); |
jiangli@8509 | 426 | super_method = superVtable->method_at(i); |
jiangli@8509 | 427 | } else { |
jiangli@8509 | 428 | super_method = method_at(i); |
jiangli@8509 | 429 | } |
duke@435 | 430 | // Check if method name matches |
coleenp@2497 | 431 | if (super_method->name() == name && super_method->signature() == signature) { |
duke@435 | 432 | |
acorn@1087 | 433 | // get super_klass for method_holder for the found method |
coleenp@4251 | 434 | InstanceKlass* super_klass = super_method->method_holder(); |
duke@435 | 435 | |
acorn@7720 | 436 | // private methods are also never overridden |
acorn@7720 | 437 | if (!super_method->is_private() && |
acorn@7720 | 438 | (is_default |
acorn@5848 | 439 | || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) |
acorn@5848 | 440 | || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) |
acorn@5848 | 441 | && ((super_klass = find_transitive_override(super_klass, |
acorn@5848 | 442 | target_method, i, target_loader, |
acorn@5848 | 443 | target_classname, THREAD)) |
acorn@7720 | 444 | != (InstanceKlass*)NULL))))) |
acorn@5848 | 445 | { |
hseigel@6759 | 446 | // Package private methods always need a new entry to root their own |
hseigel@6759 | 447 | // overriding. They may also override other methods. |
hseigel@6759 | 448 | if (!target_method()->is_package_private()) { |
hseigel@6759 | 449 | allocate_new = false; |
hseigel@6759 | 450 | } |
duke@435 | 451 | |
duke@435 | 452 | if (checkconstraints) { |
duke@435 | 453 | // Override vtable entry if passes loader constraint check |
duke@435 | 454 | // if loader constraint checking requested |
duke@435 | 455 | // No need to visit his super, since he and his super |
duke@435 | 456 | // have already made any needed loader constraints. |
duke@435 | 457 | // Since loader constraints are transitive, it is enough |
duke@435 | 458 | // to link to the first super, and we get all the others. |
duke@435 | 459 | Handle super_loader(THREAD, super_klass->class_loader()); |
duke@435 | 460 | |
acorn@1087 | 461 | if (target_loader() != super_loader()) { |
duke@435 | 462 | ResourceMark rm(THREAD); |
acorn@4840 | 463 | Symbol* failed_type_symbol = |
acorn@1087 | 464 | SystemDictionary::check_signature_loaders(signature, target_loader, |
duke@435 | 465 | super_loader, true, |
duke@435 | 466 | CHECK_(false)); |
acorn@4840 | 467 | if (failed_type_symbol != NULL) { |
duke@435 | 468 | const char* msg = "loader constraint violation: when resolving " |
duke@435 | 469 | "overridden method \"%s\" the class loader (instance" |
duke@435 | 470 | " of %s) of the current class, %s, and its superclass loader " |
duke@435 | 471 | "(instance of %s), have different Class objects for the type " |
duke@435 | 472 | "%s used in the signature"; |
duke@435 | 473 | char* sig = target_method()->name_and_sig_as_C_string(); |
acorn@1087 | 474 | const char* loader1 = SystemDictionary::loader_name(target_loader()); |
acorn@5848 | 475 | char* current = target_klass->name()->as_C_string(); |
duke@435 | 476 | const char* loader2 = SystemDictionary::loader_name(super_loader()); |
acorn@4840 | 477 | char* failed_type_name = failed_type_symbol->as_C_string(); |
duke@435 | 478 | size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
duke@435 | 479 | strlen(current) + strlen(loader2) + strlen(failed_type_name); |
duke@435 | 480 | char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
duke@435 | 481 | jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
duke@435 | 482 | failed_type_name); |
duke@435 | 483 | THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); |
duke@435 | 484 | } |
duke@435 | 485 | } |
acorn@1087 | 486 | } |
acorn@1087 | 487 | |
acorn@5848 | 488 | put_method_at(target_method(), i); |
acorn@5848 | 489 | if (!is_default) { |
acorn@5848 | 490 | target_method()->set_vtable_index(i); |
acorn@5848 | 491 | } else { |
acorn@5848 | 492 | if (def_vtable_indices != NULL) { |
jiangli@8509 | 493 | if (is_preinitialized_vtable()) { |
jiangli@8509 | 494 | // At runtime initialize_vtable is rerun as part of link_class_impl() |
jiangli@8509 | 495 | // for a shared class loaded by the non-boot loader. |
jiangli@8509 | 496 | // The dumptime vtable index should be the same as the runtime index. |
jiangli@8509 | 497 | assert(def_vtable_indices->at(default_index) == i, |
jiangli@8509 | 498 | "dump time vtable index is different from runtime index"); |
jiangli@8509 | 499 | } else { |
jiangli@8509 | 500 | def_vtable_indices->at_put(default_index, i); |
jiangli@8509 | 501 | } |
acorn@5848 | 502 | } |
acorn@5848 | 503 | assert(super_method->is_default_method() || super_method->is_overpass() |
acorn@5848 | 504 | || super_method->is_abstract(), "default override error"); |
acorn@5848 | 505 | } |
acorn@5848 | 506 | |
acorn@5848 | 507 | |
acorn@1087 | 508 | #ifndef PRODUCT |
acorn@1087 | 509 | if (PrintVtables && Verbose) { |
acorn@5848 | 510 | ResourceMark rm(THREAD); |
acorn@5848 | 511 | char* sig = target_method()->name_and_sig_as_C_string(); |
acorn@1087 | 512 | tty->print("overriding with %s::%s index %d, original flags: ", |
acorn@5848 | 513 | target_klass->internal_name(), sig, i); |
acorn@1087 | 514 | super_method->access_flags().print_on(tty); |
acorn@5848 | 515 | if (super_method->is_default_method()) { |
acorn@6080 | 516 | tty->print("default "); |
acorn@5848 | 517 | } |
acorn@5848 | 518 | if (super_method->is_overpass()) { |
acorn@5848 | 519 | tty->print("overpass"); |
acorn@5848 | 520 | } |
acorn@1087 | 521 | tty->print("overriders flags: "); |
acorn@1087 | 522 | target_method->access_flags().print_on(tty); |
acorn@5848 | 523 | if (target_method->is_default_method()) { |
acorn@6080 | 524 | tty->print("default "); |
acorn@5848 | 525 | } |
acorn@5848 | 526 | if (target_method->is_overpass()) { |
acorn@5848 | 527 | tty->print("overpass"); |
acorn@5848 | 528 | } |
acorn@1087 | 529 | tty->cr(); |
duke@435 | 530 | } |
acorn@1087 | 531 | #endif /*PRODUCT*/ |
acorn@1087 | 532 | } else { |
acorn@1087 | 533 | // allocate_new = true; default. We might override one entry, |
acorn@1087 | 534 | // but not override another. Once we override one, not need new |
duke@435 | 535 | #ifndef PRODUCT |
acorn@1087 | 536 | if (PrintVtables && Verbose) { |
acorn@5848 | 537 | ResourceMark rm(THREAD); |
acorn@5848 | 538 | char* sig = target_method()->name_and_sig_as_C_string(); |
acorn@1087 | 539 | tty->print("NOT overriding with %s::%s index %d, original flags: ", |
acorn@5848 | 540 | target_klass->internal_name(), sig,i); |
acorn@1087 | 541 | super_method->access_flags().print_on(tty); |
acorn@5848 | 542 | if (super_method->is_default_method()) { |
acorn@6080 | 543 | tty->print("default "); |
acorn@5848 | 544 | } |
acorn@5848 | 545 | if (super_method->is_overpass()) { |
acorn@5848 | 546 | tty->print("overpass"); |
acorn@5848 | 547 | } |
acorn@1087 | 548 | tty->print("overriders flags: "); |
acorn@1087 | 549 | target_method->access_flags().print_on(tty); |
acorn@5848 | 550 | if (target_method->is_default_method()) { |
acorn@6080 | 551 | tty->print("default "); |
acorn@5848 | 552 | } |
acorn@5848 | 553 | if (target_method->is_overpass()) { |
acorn@5848 | 554 | tty->print("overpass"); |
acorn@5848 | 555 | } |
acorn@1087 | 556 | tty->cr(); |
acorn@1087 | 557 | } |
duke@435 | 558 | #endif /*PRODUCT*/ |
duke@435 | 559 | } |
duke@435 | 560 | } |
duke@435 | 561 | } |
duke@435 | 562 | return allocate_new; |
duke@435 | 563 | } |
duke@435 | 564 | |
coleenp@4037 | 565 | void klassVtable::put_method_at(Method* m, int index) { |
jiangli@8509 | 566 | if (is_preinitialized_vtable()) { |
jiangli@8509 | 567 | // At runtime initialize_vtable is rerun as part of link_class_impl() |
jiangli@8509 | 568 | // for shared class loaded by the non-boot loader to obtain the loader |
jiangli@8509 | 569 | // constraints based on the runtime classloaders' context. The dumptime |
jiangli@8509 | 570 | // method at the vtable index should be the same as the runtime method. |
jiangli@8509 | 571 | assert(table()[index].method() == m, |
jiangli@8509 | 572 | "archived method is different from the runtime method"); |
jiangli@8509 | 573 | } else { |
duke@435 | 574 | #ifndef PRODUCT |
jiangli@8509 | 575 | if (PrintVtables && Verbose) { |
jiangli@8509 | 576 | ResourceMark rm; |
jiangli@8509 | 577 | const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; |
jiangli@8509 | 578 | tty->print("adding %s at index %d, flags: ", sig, index); |
jiangli@8509 | 579 | if (m != NULL) { |
jiangli@8509 | 580 | m->access_flags().print_on(tty); |
jiangli@8509 | 581 | if (m->is_default_method()) { |
jiangli@8509 | 582 | tty->print("default "); |
jiangli@8509 | 583 | } |
jiangli@8509 | 584 | if (m->is_overpass()) { |
jiangli@8509 | 585 | tty->print("overpass"); |
jiangli@8509 | 586 | } |
acorn@6080 | 587 | } |
jiangli@8509 | 588 | tty->cr(); |
acorn@6080 | 589 | } |
jiangli@8509 | 590 | #endif |
jiangli@8509 | 591 | table()[index].set(m); |
duke@435 | 592 | } |
duke@435 | 593 | } |
duke@435 | 594 | |
duke@435 | 595 | // Find out if a method "m" with superclass "super", loader "classloader" and |
duke@435 | 596 | // name "classname" needs a new vtable entry. Let P be a class package defined |
duke@435 | 597 | // by "classloader" and "classname". |
duke@435 | 598 | // NOTE: The logic used here is very similar to the one used for computing |
duke@435 | 599 | // the vtables indices for a method. We cannot directly use that function because, |
coleenp@4037 | 600 | // we allocate the InstanceKlass at load time, and that requires that the |
acorn@1087 | 601 | // superclass has been loaded. |
acorn@1087 | 602 | // However, the vtable entries are filled in at link time, and therefore |
acorn@1087 | 603 | // the superclass' vtable may not yet have been filled in. |
acorn@1087 | 604 | bool klassVtable::needs_new_vtable_entry(methodHandle target_method, |
coleenp@4037 | 605 | Klass* super, |
acorn@1087 | 606 | Handle classloader, |
coleenp@2497 | 607 | Symbol* classname, |
acorn@1087 | 608 | AccessFlags class_flags, |
acorn@1087 | 609 | TRAPS) { |
drchase@5732 | 610 | if (class_flags.is_interface()) { |
hseigel@6759 | 611 | // Interfaces do not use vtables, except for java.lang.Object methods, |
hseigel@6759 | 612 | // so there is no point to assigning |
hseigel@6759 | 613 | // a vtable index to any of their local methods. If we refrain from doing this, |
drchase@5732 | 614 | // we can use Method::_vtable_index to hold the itable index |
drchase@5732 | 615 | return false; |
drchase@5732 | 616 | } |
kamg@4245 | 617 | |
drchase@5732 | 618 | if (target_method->is_final_method(class_flags) || |
duke@435 | 619 | // a final method never needs a new entry; final methods can be statically |
duke@435 | 620 | // resolved and they have to be present in the vtable only if they override |
duke@435 | 621 | // a super's method, in which case they re-use its entry |
acorn@1087 | 622 | (target_method()->is_static()) || |
duke@435 | 623 | // static methods don't need to be in vtable |
acorn@1087 | 624 | (target_method()->name() == vmSymbols::object_initializer_name()) |
duke@435 | 625 | // <init> is never called dynamically-bound |
duke@435 | 626 | ) { |
duke@435 | 627 | return false; |
duke@435 | 628 | } |
duke@435 | 629 | |
acorn@5848 | 630 | // Concrete interface methods do not need new entries, they override |
acorn@5848 | 631 | // abstract method entries using default inheritance rules |
acorn@5848 | 632 | if (target_method()->method_holder() != NULL && |
acorn@5848 | 633 | target_method()->method_holder()->is_interface() && |
acorn@5848 | 634 | !target_method()->is_abstract() ) { |
acorn@5848 | 635 | return false; |
acorn@5848 | 636 | } |
acorn@5848 | 637 | |
duke@435 | 638 | // we need a new entry if there is no superclass |
duke@435 | 639 | if (super == NULL) { |
duke@435 | 640 | return true; |
duke@435 | 641 | } |
duke@435 | 642 | |
acorn@5786 | 643 | // private methods in classes always have a new entry in the vtable |
acorn@1087 | 644 | // specification interpretation since classic has |
acorn@1087 | 645 | // private methods not overriding |
acorn@5848 | 646 | // JDK8 adds private methods in interfaces which require invokespecial |
acorn@1087 | 647 | if (target_method()->is_private()) { |
duke@435 | 648 | return true; |
duke@435 | 649 | } |
duke@435 | 650 | |
hseigel@6759 | 651 | // Package private methods always need a new entry to root their own |
hseigel@6759 | 652 | // overriding. This allows transitive overriding to work. |
hseigel@6759 | 653 | if (target_method()->is_package_private()) { |
hseigel@6759 | 654 | return true; |
hseigel@6759 | 655 | } |
hseigel@6759 | 656 | |
duke@435 | 657 | // search through the super class hierarchy to see if we need |
duke@435 | 658 | // a new entry |
acorn@1087 | 659 | ResourceMark rm; |
coleenp@2497 | 660 | Symbol* name = target_method()->name(); |
coleenp@2497 | 661 | Symbol* signature = target_method()->signature(); |
coleenp@4037 | 662 | Klass* k = super; |
coleenp@4037 | 663 | Method* super_method = NULL; |
coleenp@4037 | 664 | InstanceKlass *holder = NULL; |
coleenp@4037 | 665 | Method* recheck_method = NULL; |
duke@435 | 666 | while (k != NULL) { |
duke@435 | 667 | // lookup through the hierarchy for a method with matching name and sign. |
coleenp@4037 | 668 | super_method = InstanceKlass::cast(k)->lookup_method(name, signature); |
acorn@1087 | 669 | if (super_method == NULL) { |
duke@435 | 670 | break; // we still have to search for a matching miranda method |
duke@435 | 671 | } |
duke@435 | 672 | // get the class holding the matching method |
acorn@1087 | 673 | // make sure you use that class for is_override |
coleenp@4251 | 674 | InstanceKlass* superk = super_method->method_holder(); |
acorn@1087 | 675 | // we want only instance method matches |
acorn@1087 | 676 | // pretend private methods are not in the super vtable |
acorn@1087 | 677 | // since we do override around them: e.g. a.m pub/b.m private/c.m pub, |
acorn@1087 | 678 | // ignore private, c.m pub does override a.m pub |
acorn@1087 | 679 | // For classes that were not javac'd together, we also do transitive overriding around |
acorn@1087 | 680 | // methods that have less accessibility |
acorn@1087 | 681 | if ((!super_method->is_static()) && |
acorn@1087 | 682 | (!super_method->is_private())) { |
acorn@1087 | 683 | if (superk->is_override(super_method, classloader, classname, THREAD)) { |
duke@435 | 684 | return false; |
acorn@1087 | 685 | // else keep looking for transitive overrides |
duke@435 | 686 | } |
duke@435 | 687 | } |
duke@435 | 688 | |
acorn@1087 | 689 | // Start with lookup result and continue to search up |
acorn@1087 | 690 | k = superk->super(); // haven't found an override match yet; continue to look |
duke@435 | 691 | } |
duke@435 | 692 | |
duke@435 | 693 | // if the target method is public or protected it may have a matching |
duke@435 | 694 | // miranda method in the super, whose entry it should re-use. |
acorn@1087 | 695 | // Actually, to handle cases that javac would not generate, we need |
acorn@1087 | 696 | // this check for all access permissions. |
coleenp@4037 | 697 | InstanceKlass *sk = InstanceKlass::cast(super); |
acorn@1087 | 698 | if (sk->has_miranda_methods()) { |
dbuck@8716 | 699 | if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) { |
acorn@1087 | 700 | return false; // found a matching miranda; we do not need a new entry |
duke@435 | 701 | } |
duke@435 | 702 | } |
duke@435 | 703 | return true; // found no match; we need a new entry |
duke@435 | 704 | } |
duke@435 | 705 | |
duke@435 | 706 | // Support for miranda methods |
duke@435 | 707 | |
duke@435 | 708 | // get the vtable index of a miranda method with matching "name" and "signature" |
coleenp@2497 | 709 | int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) { |
duke@435 | 710 | // search from the bottom, might be faster |
duke@435 | 711 | for (int i = (length() - 1); i >= 0; i--) { |
coleenp@4037 | 712 | Method* m = table()[i].method(); |
duke@435 | 713 | if (is_miranda_entry_at(i) && |
duke@435 | 714 | m->name() == name && m->signature() == signature) { |
duke@435 | 715 | return i; |
duke@435 | 716 | } |
duke@435 | 717 | } |
coleenp@4037 | 718 | return Method::invalid_vtable_index; |
duke@435 | 719 | } |
duke@435 | 720 | |
drchase@5732 | 721 | // check if an entry at an index is miranda |
drchase@5732 | 722 | // requires that method m at entry be declared ("held") by an interface. |
duke@435 | 723 | bool klassVtable::is_miranda_entry_at(int i) { |
coleenp@4037 | 724 | Method* m = method_at(i); |
coleenp@4037 | 725 | Klass* method_holder = m->method_holder(); |
coleenp@4037 | 726 | InstanceKlass *mhk = InstanceKlass::cast(method_holder); |
duke@435 | 727 | |
acorn@5786 | 728 | // miranda methods are public abstract instance interface methods in a class's vtable |
duke@435 | 729 | if (mhk->is_interface()) { |
kamg@4245 | 730 | assert(m->is_public(), "should be public"); |
duke@435 | 731 | assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); |
acorn@6080 | 732 | if (is_miranda(m, ik()->methods(), ik()->default_methods(), ik()->super())) { |
acorn@6080 | 733 | return true; |
acorn@6080 | 734 | } |
duke@435 | 735 | } |
duke@435 | 736 | return false; |
duke@435 | 737 | } |
duke@435 | 738 | |
dbuck@8716 | 739 | // Check if a method is a miranda method, given a class's methods array, |
dbuck@8716 | 740 | // its default_method table and its super class. |
dbuck@8716 | 741 | // "Miranda" means an abstract non-private method that would not be |
dbuck@8716 | 742 | // overridden for the local class. |
dbuck@8716 | 743 | // A "miranda" method should only include non-private interface |
dbuck@8716 | 744 | // instance methods, i.e. not private methods, not static methods, |
dbuck@8716 | 745 | // not default methods (concrete interface methods), not overpass methods. |
dbuck@8716 | 746 | // If a given class already has a local (including overpass) method, a |
dbuck@8716 | 747 | // default method, or any of its superclasses has the same which would have |
dbuck@8716 | 748 | // overridden an abstract method, then this is not a miranda method. |
dbuck@8716 | 749 | // |
dbuck@8716 | 750 | // Miranda methods are checked multiple times. |
dbuck@8716 | 751 | // Pass 1: during class load/class file parsing: before vtable size calculation: |
dbuck@8716 | 752 | // include superinterface abstract and default methods (non-private instance). |
acorn@7720 | 753 | // We include potential default methods to give them space in the vtable. |
dbuck@8716 | 754 | // During the first run, the current instanceKlass has not yet been |
dbuck@8716 | 755 | // created, the superclasses and superinterfaces do have instanceKlasses |
dbuck@8716 | 756 | // but may not have vtables, the default_methods list is empty, no overpasses. |
dbuck@8716 | 757 | // This is seen by default method creation. |
dbuck@8716 | 758 | // |
dbuck@8716 | 759 | // Pass 2: recalculated during vtable initialization: only include abstract methods. |
dbuck@8716 | 760 | // The goal of pass 2 is to walk through the superinterfaces to see if any of |
dbuck@8716 | 761 | // the superinterface methods (which were all abstract pre-default methods) |
dbuck@8716 | 762 | // need to be added to the vtable. |
dbuck@8716 | 763 | // With the addition of default methods, we have three new challenges: |
dbuck@8716 | 764 | // overpasses, static interface methods and private interface methods. |
dbuck@8716 | 765 | // Static and private interface methods do not get added to the vtable and |
dbuck@8716 | 766 | // are not seen by the method resolution process, so we skip those. |
dbuck@8716 | 767 | // Overpass methods are already in the vtable, so vtable lookup will |
dbuck@8716 | 768 | // find them and we don't need to add a miranda method to the end of |
dbuck@8716 | 769 | // the vtable. So we look for overpass methods and if they are found we |
dbuck@8716 | 770 | // return false. Note that we inherit our superclasses vtable, so |
dbuck@8716 | 771 | // the superclass' search also needs to use find_overpass so that if |
dbuck@8716 | 772 | // one is found we return false. |
dbuck@8716 | 773 | // False means - we don't need a miranda method added to the vtable. |
dbuck@8716 | 774 | // |
acorn@7720 | 775 | // During the second run, default_methods is set up, so concrete methods from |
acorn@7720 | 776 | // superinterfaces with matching names/signatures to default_methods are already |
acorn@7720 | 777 | // in the default_methods list and do not need to be appended to the vtable |
dbuck@8716 | 778 | // as mirandas. Abstract methods may already have been handled via |
dbuck@8716 | 779 | // overpasses - either local or superclass overpasses, which may be |
dbuck@8716 | 780 | // in the vtable already. |
dbuck@8716 | 781 | // |
dbuck@8716 | 782 | // Pass 3: They are also checked by link resolution and selection, |
dbuck@8716 | 783 | // for invocation on a method (not interface method) reference that |
dbuck@8716 | 784 | // resolves to a method with an interface as its method_holder. |
dbuck@8716 | 785 | // Used as part of walking from the bottom of the vtable to find |
dbuck@8716 | 786 | // the vtable index for the miranda method. |
dbuck@8716 | 787 | // |
dbuck@8716 | 788 | // Part of the Miranda Rights in the US mean that if you do not have |
dbuck@8716 | 789 | // an attorney one will be appointed for you. |
acorn@5848 | 790 | bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, |
acorn@5848 | 791 | Array<Method*>* default_methods, Klass* super) { |
acorn@6080 | 792 | if (m->is_static() || m->is_private() || m->is_overpass()) { |
bharadwaj@4998 | 793 | return false; |
bharadwaj@4998 | 794 | } |
coleenp@2497 | 795 | Symbol* name = m->name(); |
coleenp@2497 | 796 | Symbol* signature = m->signature(); |
acorn@6145 | 797 | |
dbuck@8716 | 798 | // First look in local methods to see if already covered |
dbuck@8716 | 799 | if (InstanceKlass::find_local_method(class_methods, name, signature, |
dbuck@8716 | 800 | Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) |
dbuck@8716 | 801 | { |
dbuck@8716 | 802 | return false; |
duke@435 | 803 | } |
dsamersoff@2360 | 804 | |
dbuck@8716 | 805 | // Check local default methods |
dbuck@8716 | 806 | if ((default_methods != NULL) && |
dbuck@8716 | 807 | (InstanceKlass::find_method(default_methods, name, signature) != NULL)) |
dbuck@8716 | 808 | { |
dbuck@8716 | 809 | return false; |
dbuck@8716 | 810 | } |
dbuck@8716 | 811 | |
dbuck@8716 | 812 | InstanceKlass* cursuper; |
dbuck@8716 | 813 | // Iterate on all superclasses, which should have instanceKlasses |
dbuck@8716 | 814 | // Note that we explicitly look for overpasses at each level. |
dbuck@8716 | 815 | // Overpasses may or may not exist for supers for pass 1, |
dbuck@8716 | 816 | // they should have been created for pass 2 and later. |
dbuck@8716 | 817 | |
dbuck@8716 | 818 | for (cursuper = InstanceKlass::cast(super); cursuper != NULL; cursuper = (InstanceKlass*)cursuper->super()) |
dbuck@8716 | 819 | { |
dbuck@8716 | 820 | if (cursuper->find_local_method(name, signature, |
dbuck@8716 | 821 | Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) { |
dbuck@8716 | 822 | return false; |
dbuck@8716 | 823 | } |
dbuck@8716 | 824 | } |
dbuck@8716 | 825 | |
dbuck@8716 | 826 | return true; |
duke@435 | 827 | } |
duke@435 | 828 | |
drchase@5732 | 829 | // Scans current_interface_methods for miranda methods that do not |
acorn@5848 | 830 | // already appear in new_mirandas, or default methods, and are also not defined-and-non-private |
drchase@5732 | 831 | // in super (superclass). These mirandas are added to all_mirandas if it is |
drchase@5732 | 832 | // not null; in addition, those that are not duplicates of miranda methods |
drchase@5732 | 833 | // inherited by super from its interfaces are added to new_mirandas. |
drchase@5732 | 834 | // Thus, new_mirandas will be the set of mirandas that this class introduces, |
drchase@5732 | 835 | // all_mirandas will be the set of all mirandas applicable to this class |
drchase@5732 | 836 | // including all defined in superclasses. |
kamg@4245 | 837 | void klassVtable::add_new_mirandas_to_lists( |
kamg@4245 | 838 | GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas, |
kamg@4245 | 839 | Array<Method*>* current_interface_methods, Array<Method*>* class_methods, |
acorn@5848 | 840 | Array<Method*>* default_methods, Klass* super) { |
acorn@5848 | 841 | |
duke@435 | 842 | // iterate thru the current interface's method to see if it a miranda |
duke@435 | 843 | int num_methods = current_interface_methods->length(); |
duke@435 | 844 | for (int i = 0; i < num_methods; i++) { |
coleenp@4037 | 845 | Method* im = current_interface_methods->at(i); |
duke@435 | 846 | bool is_duplicate = false; |
kamg@4245 | 847 | int num_of_current_mirandas = new_mirandas->length(); |
duke@435 | 848 | // check for duplicate mirandas in different interfaces we implement |
duke@435 | 849 | for (int j = 0; j < num_of_current_mirandas; j++) { |
kamg@4245 | 850 | Method* miranda = new_mirandas->at(j); |
duke@435 | 851 | if ((im->name() == miranda->name()) && |
duke@435 | 852 | (im->signature() == miranda->signature())) { |
duke@435 | 853 | is_duplicate = true; |
duke@435 | 854 | break; |
duke@435 | 855 | } |
duke@435 | 856 | } |
duke@435 | 857 | |
duke@435 | 858 | if (!is_duplicate) { // we don't want duplicate miranda entries in the vtable |
acorn@5848 | 859 | if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all? |
coleenp@4037 | 860 | InstanceKlass *sk = InstanceKlass::cast(super); |
duke@435 | 861 | // check if it is a duplicate of a super's miranda |
dbuck@8716 | 862 | if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::find_defaults) == NULL) { |
kamg@4245 | 863 | new_mirandas->append(im); |
kamg@4245 | 864 | } |
kamg@4245 | 865 | if (all_mirandas != NULL) { |
kamg@4245 | 866 | all_mirandas->append(im); |
duke@435 | 867 | } |
duke@435 | 868 | } |
duke@435 | 869 | } |
duke@435 | 870 | } |
duke@435 | 871 | } |
duke@435 | 872 | |
kamg@4245 | 873 | void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas, |
kamg@4245 | 874 | GrowableArray<Method*>* all_mirandas, |
coleenp@4037 | 875 | Klass* super, Array<Method*>* class_methods, |
acorn@5848 | 876 | Array<Method*>* default_methods, |
coleenp@4037 | 877 | Array<Klass*>* local_interfaces) { |
kamg@4245 | 878 | assert((new_mirandas->length() == 0) , "current mirandas must be 0"); |
duke@435 | 879 | |
duke@435 | 880 | // iterate thru the local interfaces looking for a miranda |
duke@435 | 881 | int num_local_ifs = local_interfaces->length(); |
duke@435 | 882 | for (int i = 0; i < num_local_ifs; i++) { |
coleenp@4037 | 883 | InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i)); |
kamg@4245 | 884 | add_new_mirandas_to_lists(new_mirandas, all_mirandas, |
acorn@5848 | 885 | ik->methods(), class_methods, |
acorn@5848 | 886 | default_methods, super); |
duke@435 | 887 | // iterate thru each local's super interfaces |
coleenp@4037 | 888 | Array<Klass*>* super_ifs = ik->transitive_interfaces(); |
duke@435 | 889 | int num_super_ifs = super_ifs->length(); |
duke@435 | 890 | for (int j = 0; j < num_super_ifs; j++) { |
coleenp@4037 | 891 | InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j)); |
kamg@4245 | 892 | add_new_mirandas_to_lists(new_mirandas, all_mirandas, |
acorn@5848 | 893 | sik->methods(), class_methods, |
acorn@5848 | 894 | default_methods, super); |
duke@435 | 895 | } |
duke@435 | 896 | } |
duke@435 | 897 | } |
duke@435 | 898 | |
drchase@5732 | 899 | // Discover miranda methods ("miranda" = "interface abstract, no binding"), |
drchase@5732 | 900 | // and append them into the vtable starting at index initialized, |
drchase@5732 | 901 | // return the new value of initialized. |
acorn@6080 | 902 | // Miranda methods use vtable entries, but do not get assigned a vtable_index |
acorn@6080 | 903 | // The vtable_index is discovered by searching from the end of the vtable |
drchase@5732 | 904 | int klassVtable::fill_in_mirandas(int initialized) { |
kamg@4245 | 905 | GrowableArray<Method*> mirandas(20); |
kamg@4245 | 906 | get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), |
acorn@5848 | 907 | ik()->default_methods(), ik()->local_interfaces()); |
kamg@4245 | 908 | for (int i = 0; i < mirandas.length(); i++) { |
acorn@5848 | 909 | if (PrintVtables && Verbose) { |
acorn@5848 | 910 | Method* meth = mirandas.at(i); |
acorn@5848 | 911 | ResourceMark rm(Thread::current()); |
acorn@5848 | 912 | if (meth != NULL) { |
acorn@5848 | 913 | char* sig = meth->name_and_sig_as_C_string(); |
acorn@5848 | 914 | tty->print("fill in mirandas with %s index %d, flags: ", |
acorn@5848 | 915 | sig, initialized); |
acorn@5848 | 916 | meth->access_flags().print_on(tty); |
acorn@5848 | 917 | if (meth->is_default_method()) { |
acorn@6080 | 918 | tty->print("default "); |
acorn@5848 | 919 | } |
acorn@5848 | 920 | tty->cr(); |
acorn@5848 | 921 | } |
acorn@5848 | 922 | } |
drchase@5732 | 923 | put_method_at(mirandas.at(i), initialized); |
drchase@5732 | 924 | ++initialized; |
duke@435 | 925 | } |
drchase@5732 | 926 | return initialized; |
duke@435 | 927 | } |
duke@435 | 928 | |
drchase@5732 | 929 | // Copy this class's vtable to the vtable beginning at start. |
drchase@5732 | 930 | // Used to copy superclass vtable to prefix of subclass's vtable. |
duke@435 | 931 | void klassVtable::copy_vtable_to(vtableEntry* start) { |
duke@435 | 932 | Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); |
duke@435 | 933 | } |
duke@435 | 934 | |
dcubed@4562 | 935 | #if INCLUDE_JVMTI |
acorn@5848 | 936 | bool klassVtable::adjust_default_method(int vtable_index, Method* old_method, Method* new_method) { |
acorn@5848 | 937 | // If old_method is default, find this vtable index in default_vtable_indices |
acorn@5848 | 938 | // and replace that method in the _default_methods list |
acorn@5848 | 939 | bool updated = false; |
acorn@5848 | 940 | |
acorn@5848 | 941 | Array<Method*>* default_methods = ik()->default_methods(); |
acorn@5848 | 942 | if (default_methods != NULL) { |
acorn@5848 | 943 | int len = default_methods->length(); |
acorn@5848 | 944 | for (int idx = 0; idx < len; idx++) { |
acorn@5848 | 945 | if (vtable_index == ik()->default_vtable_indices()->at(idx)) { |
acorn@5848 | 946 | if (default_methods->at(idx) == old_method) { |
acorn@5848 | 947 | default_methods->at_put(idx, new_method); |
acorn@5848 | 948 | updated = true; |
acorn@5848 | 949 | } |
acorn@5848 | 950 | break; |
acorn@5848 | 951 | } |
acorn@5848 | 952 | } |
acorn@5848 | 953 | } |
acorn@5848 | 954 | return updated; |
acorn@5848 | 955 | } |
duke@435 | 956 | |
sspitsyn@7636 | 957 | // search the vtable for uses of either obsolete or EMCP methods |
sspitsyn@7636 | 958 | void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { |
sspitsyn@7636 | 959 | int prn_enabled = 0; |
sspitsyn@7636 | 960 | for (int index = 0; index < length(); index++) { |
sspitsyn@7636 | 961 | Method* old_method = unchecked_method_at(index); |
sspitsyn@7636 | 962 | if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { |
sspitsyn@7636 | 963 | continue; // skip uninteresting entries |
sspitsyn@7636 | 964 | } |
sspitsyn@7636 | 965 | assert(!old_method->is_deleted(), "vtable methods may not be deleted"); |
duke@435 | 966 | |
sspitsyn@7636 | 967 | Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); |
sspitsyn@7636 | 968 | |
sspitsyn@7636 | 969 | assert(new_method != NULL, "method_with_idnum() should not be NULL"); |
sspitsyn@7636 | 970 | assert(old_method != new_method, "sanity check"); |
sspitsyn@7636 | 971 | |
sspitsyn@7636 | 972 | put_method_at(new_method, index); |
sspitsyn@7636 | 973 | // For default methods, need to update the _default_methods array |
sspitsyn@7636 | 974 | // which can only have one method entry for a given signature |
sspitsyn@7636 | 975 | bool updated_default = false; |
sspitsyn@7636 | 976 | if (old_method->is_default_method()) { |
sspitsyn@7636 | 977 | updated_default = adjust_default_method(index, old_method, new_method); |
sspitsyn@7636 | 978 | } |
sspitsyn@7636 | 979 | |
sspitsyn@7636 | 980 | if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { |
sspitsyn@7636 | 981 | if (!(*trace_name_printed)) { |
sspitsyn@7636 | 982 | // RC_TRACE_MESG macro has an embedded ResourceMark |
sspitsyn@7636 | 983 | RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s", |
sspitsyn@7636 | 984 | klass()->external_name(), |
sspitsyn@7636 | 985 | old_method->method_holder()->external_name())); |
sspitsyn@7636 | 986 | *trace_name_printed = true; |
duke@435 | 987 | } |
sspitsyn@7636 | 988 | // RC_TRACE macro has an embedded ResourceMark |
sspitsyn@7636 | 989 | RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s", |
sspitsyn@7636 | 990 | new_method->name()->as_C_string(), |
sspitsyn@7636 | 991 | new_method->signature()->as_C_string(), |
sspitsyn@7636 | 992 | updated_default ? "true" : "false")); |
duke@435 | 993 | } |
duke@435 | 994 | } |
duke@435 | 995 | } |
duke@435 | 996 | |
dcubed@4562 | 997 | // a vtable should never contain old or obsolete methods |
dcubed@4562 | 998 | bool klassVtable::check_no_old_or_obsolete_entries() { |
dcubed@4562 | 999 | for (int i = 0; i < length(); i++) { |
dcubed@4562 | 1000 | Method* m = unchecked_method_at(i); |
dcubed@4562 | 1001 | if (m != NULL && |
dcubed@4562 | 1002 | (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) { |
dcubed@4562 | 1003 | return false; |
dcubed@4562 | 1004 | } |
dcubed@4562 | 1005 | } |
dcubed@4562 | 1006 | return true; |
dcubed@4562 | 1007 | } |
dcubed@4562 | 1008 | |
dcubed@4562 | 1009 | void klassVtable::dump_vtable() { |
dcubed@4562 | 1010 | tty->print_cr("vtable dump --"); |
dcubed@4562 | 1011 | for (int i = 0; i < length(); i++) { |
dcubed@4562 | 1012 | Method* m = unchecked_method_at(i); |
dcubed@4562 | 1013 | if (m != NULL) { |
dcubed@4562 | 1014 | tty->print(" (%5d) ", i); |
dcubed@4562 | 1015 | m->access_flags().print_on(tty); |
acorn@5848 | 1016 | if (m->is_default_method()) { |
acorn@6080 | 1017 | tty->print("default "); |
acorn@5848 | 1018 | } |
acorn@5848 | 1019 | if (m->is_overpass()) { |
acorn@5848 | 1020 | tty->print("overpass"); |
acorn@5848 | 1021 | } |
dcubed@4562 | 1022 | tty->print(" -- "); |
dcubed@4562 | 1023 | m->print_name(tty); |
dcubed@4562 | 1024 | tty->cr(); |
dcubed@4562 | 1025 | } |
dcubed@4562 | 1026 | } |
dcubed@4562 | 1027 | } |
dcubed@4562 | 1028 | #endif // INCLUDE_JVMTI |
dcubed@4562 | 1029 | |
coleenp@2777 | 1030 | // CDS/RedefineClasses support - clear vtables so they can be reinitialized |
coleenp@2777 | 1031 | void klassVtable::clear_vtable() { |
coleenp@2777 | 1032 | for (int i = 0; i < _length; i++) table()[i].clear(); |
coleenp@2777 | 1033 | } |
coleenp@2777 | 1034 | |
coleenp@2777 | 1035 | bool klassVtable::is_initialized() { |
coleenp@2777 | 1036 | return _length == 0 || table()[0].method() != NULL; |
coleenp@2777 | 1037 | } |
coleenp@2777 | 1038 | |
duke@435 | 1039 | //----------------------------------------------------------------------------------------- |
duke@435 | 1040 | // Itable code |
duke@435 | 1041 | |
duke@435 | 1042 | // Initialize a itableMethodEntry |
coleenp@4037 | 1043 | void itableMethodEntry::initialize(Method* m) { |
duke@435 | 1044 | if (m == NULL) return; |
duke@435 | 1045 | |
jiangli@8509 | 1046 | if (MetaspaceShared::is_in_shared_space((void*)&_method) && |
jiangli@8509 | 1047 | !MetaspaceShared::remapped_readwrite()) { |
jiangli@8509 | 1048 | // At runtime initialize_itable is rerun as part of link_class_impl() |
jiangli@8509 | 1049 | // for a shared class loaded by the non-boot loader. |
jiangli@8509 | 1050 | // The dumptime itable method entry should be the same as the runtime entry. |
jiangli@8509 | 1051 | assert(_method == m, "sanity"); |
jiangli@8509 | 1052 | } else { |
jiangli@8509 | 1053 | _method = m; |
jiangli@8509 | 1054 | } |
duke@435 | 1055 | } |
duke@435 | 1056 | |
duke@435 | 1057 | klassItable::klassItable(instanceKlassHandle klass) { |
duke@435 | 1058 | _klass = klass; |
duke@435 | 1059 | |
duke@435 | 1060 | if (klass->itable_length() > 0) { |
duke@435 | 1061 | itableOffsetEntry* offset_entry = (itableOffsetEntry*)klass->start_of_itable(); |
duke@435 | 1062 | if (offset_entry != NULL && offset_entry->interface_klass() != NULL) { // Check that itable is initialized |
duke@435 | 1063 | // First offset entry points to the first method_entry |
coleenp@4037 | 1064 | intptr_t* method_entry = (intptr_t *)(((address)klass()) + offset_entry->offset()); |
duke@435 | 1065 | intptr_t* end = klass->end_of_itable(); |
duke@435 | 1066 | |
coleenp@4037 | 1067 | _table_offset = (intptr_t*)offset_entry - (intptr_t*)klass(); |
duke@435 | 1068 | _size_offset_table = (method_entry - ((intptr_t*)offset_entry)) / itableOffsetEntry::size(); |
duke@435 | 1069 | _size_method_table = (end - method_entry) / itableMethodEntry::size(); |
duke@435 | 1070 | assert(_table_offset >= 0 && _size_offset_table >= 0 && _size_method_table >= 0, "wrong computation"); |
duke@435 | 1071 | return; |
duke@435 | 1072 | } |
duke@435 | 1073 | } |
duke@435 | 1074 | |
dcubed@451 | 1075 | // The length of the itable was either zero, or it has not yet been initialized. |
duke@435 | 1076 | _table_offset = 0; |
duke@435 | 1077 | _size_offset_table = 0; |
duke@435 | 1078 | _size_method_table = 0; |
duke@435 | 1079 | } |
duke@435 | 1080 | |
duke@435 | 1081 | static int initialize_count = 0; |
duke@435 | 1082 | |
duke@435 | 1083 | // Initialization |
duke@435 | 1084 | void klassItable::initialize_itable(bool checkconstraints, TRAPS) { |
drchase@5732 | 1085 | if (_klass->is_interface()) { |
acorn@5848 | 1086 | // This needs to go after vtable indices are assigned but |
acorn@5848 | 1087 | // before implementors need to know the number of itable indices. |
acorn@5848 | 1088 | assign_itable_indices_for_interface(_klass()); |
drchase@5732 | 1089 | } |
drchase@5732 | 1090 | |
dcubed@451 | 1091 | // Cannot be setup doing bootstrapping, interfaces don't have |
dcubed@451 | 1092 | // itables, and klass with only ones entry have empty itables |
dcubed@451 | 1093 | if (Universe::is_bootstrapping() || |
dcubed@451 | 1094 | _klass->is_interface() || |
dcubed@451 | 1095 | _klass->itable_length() == itableOffsetEntry::size()) return; |
duke@435 | 1096 | |
dcubed@451 | 1097 | // There's alway an extra itable entry so we can null-terminate it. |
dcubed@451 | 1098 | guarantee(size_offset_table() >= 1, "too small"); |
dcubed@451 | 1099 | int num_interfaces = size_offset_table() - 1; |
duke@435 | 1100 | if (num_interfaces > 0) { |
dcubed@451 | 1101 | if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, |
dcubed@451 | 1102 | _klass->name()->as_C_string()); |
duke@435 | 1103 | |
duke@435 | 1104 | |
acorn@1087 | 1105 | // Iterate through all interfaces |
duke@435 | 1106 | int i; |
duke@435 | 1107 | for(i = 0; i < num_interfaces; i++) { |
duke@435 | 1108 | itableOffsetEntry* ioe = offset_entry(i); |
coleenp@4037 | 1109 | HandleMark hm(THREAD); |
duke@435 | 1110 | KlassHandle interf_h (THREAD, ioe->interface_klass()); |
duke@435 | 1111 | assert(interf_h() != NULL && ioe->offset() != 0, "bad offset entry in itable"); |
duke@435 | 1112 | initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK); |
duke@435 | 1113 | } |
duke@435 | 1114 | |
duke@435 | 1115 | } |
dcubed@451 | 1116 | // Check that the last entry is empty |
dcubed@451 | 1117 | itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1); |
dcubed@451 | 1118 | guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing"); |
duke@435 | 1119 | } |
duke@435 | 1120 | |
duke@435 | 1121 | |
drchase@5732 | 1122 | inline bool interface_method_needs_itable_index(Method* m) { |
drchase@5732 | 1123 | if (m->is_static()) return false; // e.g., Stream.empty |
drchase@5732 | 1124 | if (m->is_initializer()) return false; // <init> or <clinit> |
drchase@5732 | 1125 | // If an interface redeclares a method from java.lang.Object, |
drchase@5732 | 1126 | // it should already have a vtable index, don't touch it. |
drchase@5732 | 1127 | // e.g., CharSequence.toString (from initialize_vtable) |
drchase@5732 | 1128 | // if (m->has_vtable_index()) return false; // NO! |
drchase@5732 | 1129 | return true; |
drchase@5732 | 1130 | } |
drchase@5732 | 1131 | |
acorn@5848 | 1132 | int klassItable::assign_itable_indices_for_interface(Klass* klass) { |
drchase@5732 | 1133 | // an interface does not have an itable, but its methods need to be numbered |
drchase@5732 | 1134 | if (TraceItables) tty->print_cr("%3d: Initializing itable for interface %s", ++initialize_count, |
drchase@5732 | 1135 | klass->name()->as_C_string()); |
drchase@5732 | 1136 | Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); |
drchase@5732 | 1137 | int nof_methods = methods->length(); |
drchase@5732 | 1138 | int ime_num = 0; |
drchase@5732 | 1139 | for (int i = 0; i < nof_methods; i++) { |
drchase@5732 | 1140 | Method* m = methods->at(i); |
drchase@5732 | 1141 | if (interface_method_needs_itable_index(m)) { |
drchase@5732 | 1142 | assert(!m->is_final_method(), "no final interface methods"); |
drchase@5732 | 1143 | // If m is already assigned a vtable index, do not disturb it. |
acorn@6080 | 1144 | if (TraceItables && Verbose) { |
acorn@6080 | 1145 | ResourceMark rm; |
acorn@6080 | 1146 | const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; |
acorn@6080 | 1147 | if (m->has_vtable_index()) { |
acorn@6080 | 1148 | tty->print("itable index %d for method: %s, flags: ", m->vtable_index(), sig); |
acorn@6080 | 1149 | } else { |
acorn@6080 | 1150 | tty->print("itable index %d for method: %s, flags: ", ime_num, sig); |
acorn@6080 | 1151 | } |
acorn@6080 | 1152 | if (m != NULL) { |
acorn@6080 | 1153 | m->access_flags().print_on(tty); |
acorn@6080 | 1154 | if (m->is_default_method()) { |
acorn@6080 | 1155 | tty->print("default "); |
acorn@6080 | 1156 | } |
acorn@6080 | 1157 | if (m->is_overpass()) { |
acorn@6080 | 1158 | tty->print("overpass"); |
acorn@6080 | 1159 | } |
acorn@6080 | 1160 | } |
acorn@6080 | 1161 | tty->cr(); |
acorn@6080 | 1162 | } |
drchase@5732 | 1163 | if (!m->has_vtable_index()) { |
jiangli@8509 | 1164 | // A shared method could have an initialized itable_index that |
jiangli@8509 | 1165 | // is < 0. |
jiangli@8509 | 1166 | assert(m->vtable_index() == Method::pending_itable_index || |
jiangli@8509 | 1167 | m->is_shared(), |
jiangli@8509 | 1168 | "set by initialize_vtable"); |
drchase@5732 | 1169 | m->set_itable_index(ime_num); |
drchase@5732 | 1170 | // Progress to next itable entry |
drchase@5732 | 1171 | ime_num++; |
drchase@5732 | 1172 | } |
drchase@5732 | 1173 | } |
drchase@5732 | 1174 | } |
drchase@5732 | 1175 | assert(ime_num == method_count_for_interface(klass), "proper sizing"); |
drchase@5732 | 1176 | return ime_num; |
drchase@5732 | 1177 | } |
drchase@5732 | 1178 | |
drchase@5732 | 1179 | int klassItable::method_count_for_interface(Klass* interf) { |
drchase@5732 | 1180 | assert(interf->oop_is_instance(), "must be"); |
drchase@5732 | 1181 | assert(interf->is_interface(), "must be"); |
drchase@5732 | 1182 | Array<Method*>* methods = InstanceKlass::cast(interf)->methods(); |
drchase@5732 | 1183 | int nof_methods = methods->length(); |
drchase@5732 | 1184 | while (nof_methods > 0) { |
drchase@5732 | 1185 | Method* m = methods->at(nof_methods-1); |
drchase@5732 | 1186 | if (m->has_itable_index()) { |
drchase@5732 | 1187 | int length = m->itable_index() + 1; |
drchase@5732 | 1188 | #ifdef ASSERT |
drchase@5732 | 1189 | while (nof_methods = 0) { |
drchase@5732 | 1190 | m = methods->at(--nof_methods); |
drchase@5732 | 1191 | assert(!m->has_itable_index() || m->itable_index() < length, ""); |
drchase@5732 | 1192 | } |
drchase@5732 | 1193 | #endif //ASSERT |
drchase@5732 | 1194 | return length; // return the rightmost itable index, plus one |
drchase@5732 | 1195 | } |
drchase@5732 | 1196 | nof_methods -= 1; |
drchase@5732 | 1197 | } |
acorn@5848 | 1198 | // no methods have itable indices |
drchase@5732 | 1199 | return 0; |
drchase@5732 | 1200 | } |
drchase@5732 | 1201 | |
drchase@5732 | 1202 | |
duke@435 | 1203 | void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) { |
coleenp@4037 | 1204 | Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods(); |
coleenp@4037 | 1205 | int nof_methods = methods->length(); |
duke@435 | 1206 | HandleMark hm; |
coleenp@4037 | 1207 | Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader()); |
duke@435 | 1208 | |
drchase@5732 | 1209 | int ime_count = method_count_for_interface(interf_h()); |
drchase@5732 | 1210 | for (int i = 0; i < nof_methods; i++) { |
coleenp@4037 | 1211 | Method* m = methods->at(i); |
drchase@5732 | 1212 | methodHandle target; |
drchase@5732 | 1213 | if (m->has_itable_index()) { |
hseigel@6195 | 1214 | // This search must match the runtime resolution, i.e. selection search for invokeinterface |
hseigel@6195 | 1215 | // to correctly enforce loader constraints for interface method inheritance |
drchase@5732 | 1216 | LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK); |
duke@435 | 1217 | } |
duke@435 | 1218 | if (target == NULL || !target->is_public() || target->is_abstract()) { |
drchase@6134 | 1219 | // Entry does not resolve. Leave it empty for AbstractMethodError. |
drchase@6134 | 1220 | if (!(target == NULL) && !target->is_public()) { |
drchase@6134 | 1221 | // Stuff an IllegalAccessError throwing method in there instead. |
drchase@6134 | 1222 | itableOffsetEntry::method_entry(_klass(), method_table_offset)[m->itable_index()]. |
drchase@6134 | 1223 | initialize(Universe::throw_illegal_access_error()); |
drchase@6134 | 1224 | } |
duke@435 | 1225 | } else { |
duke@435 | 1226 | // Entry did resolve, check loader constraints before initializing |
duke@435 | 1227 | // if checkconstraints requested |
duke@435 | 1228 | if (checkconstraints) { |
coleenp@4251 | 1229 | Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); |
duke@435 | 1230 | if (method_holder_loader() != interface_loader()) { |
duke@435 | 1231 | ResourceMark rm(THREAD); |
acorn@4840 | 1232 | Symbol* failed_type_symbol = |
drchase@5732 | 1233 | SystemDictionary::check_signature_loaders(m->signature(), |
duke@435 | 1234 | method_holder_loader, |
duke@435 | 1235 | interface_loader, |
duke@435 | 1236 | true, CHECK); |
acorn@4840 | 1237 | if (failed_type_symbol != NULL) { |
duke@435 | 1238 | const char* msg = "loader constraint violation in interface " |
duke@435 | 1239 | "itable initialization: when resolving method \"%s\" the class" |
duke@435 | 1240 | " loader (instance of %s) of the current class, %s, " |
duke@435 | 1241 | "and the class loader (instance of %s) for interface " |
duke@435 | 1242 | "%s have different Class objects for the type %s " |
duke@435 | 1243 | "used in the signature"; |
drchase@5732 | 1244 | char* sig = target()->name_and_sig_as_C_string(); |
duke@435 | 1245 | const char* loader1 = SystemDictionary::loader_name(method_holder_loader()); |
drchase@5732 | 1246 | char* current = _klass->name()->as_C_string(); |
duke@435 | 1247 | const char* loader2 = SystemDictionary::loader_name(interface_loader()); |
coleenp@4037 | 1248 | char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string(); |
acorn@4840 | 1249 | char* failed_type_name = failed_type_symbol->as_C_string(); |
duke@435 | 1250 | size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
duke@435 | 1251 | strlen(current) + strlen(loader2) + strlen(iface) + |
duke@435 | 1252 | strlen(failed_type_name); |
duke@435 | 1253 | char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
duke@435 | 1254 | jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
duke@435 | 1255 | iface, failed_type_name); |
duke@435 | 1256 | THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
duke@435 | 1257 | } |
duke@435 | 1258 | } |
duke@435 | 1259 | } |
duke@435 | 1260 | |
duke@435 | 1261 | // ime may have moved during GC so recalculate address |
drchase@5732 | 1262 | int ime_num = m->itable_index(); |
drchase@5732 | 1263 | assert(ime_num < ime_count, "oob"); |
drchase@5732 | 1264 | itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); |
acorn@5848 | 1265 | if (TraceItables && Verbose) { |
acorn@5848 | 1266 | ResourceMark rm(THREAD); |
acorn@5848 | 1267 | if (target() != NULL) { |
acorn@5848 | 1268 | char* sig = target()->name_and_sig_as_C_string(); |
acorn@5848 | 1269 | tty->print("interface: %s, ime_num: %d, target: %s, method_holder: %s ", |
acorn@5848 | 1270 | interf_h()->internal_name(), ime_num, sig, |
acorn@5848 | 1271 | target()->method_holder()->internal_name()); |
acorn@5848 | 1272 | tty->print("target_method flags: "); |
acorn@5848 | 1273 | target()->access_flags().print_on(tty); |
acorn@5848 | 1274 | if (target()->is_default_method()) { |
acorn@6080 | 1275 | tty->print("default "); |
acorn@5848 | 1276 | } |
acorn@5848 | 1277 | tty->cr(); |
acorn@5848 | 1278 | } |
acorn@5848 | 1279 | } |
duke@435 | 1280 | } |
duke@435 | 1281 | } |
duke@435 | 1282 | } |
duke@435 | 1283 | |
coleenp@4037 | 1284 | // Update entry for specific Method* |
coleenp@4037 | 1285 | void klassItable::initialize_with_method(Method* m) { |
duke@435 | 1286 | itableMethodEntry* ime = method_entry(0); |
duke@435 | 1287 | for(int i = 0; i < _size_method_table; i++) { |
duke@435 | 1288 | if (ime->method() == m) { |
duke@435 | 1289 | ime->initialize(m); |
duke@435 | 1290 | } |
duke@435 | 1291 | ime++; |
duke@435 | 1292 | } |
duke@435 | 1293 | } |
duke@435 | 1294 | |
dcubed@4562 | 1295 | #if INCLUDE_JVMTI |
sspitsyn@7636 | 1296 | // search the itable for uses of either obsolete or EMCP methods |
sspitsyn@7636 | 1297 | void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { |
duke@435 | 1298 | |
sspitsyn@7636 | 1299 | itableMethodEntry* ime = method_entry(0); |
sspitsyn@7636 | 1300 | for (int i = 0; i < _size_method_table; i++, ime++) { |
sspitsyn@7636 | 1301 | Method* old_method = ime->method(); |
sspitsyn@7636 | 1302 | if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { |
sspitsyn@7636 | 1303 | continue; // skip uninteresting entries |
sspitsyn@7636 | 1304 | } |
sspitsyn@7636 | 1305 | assert(!old_method->is_deleted(), "itable methods may not be deleted"); |
duke@435 | 1306 | |
sspitsyn@7636 | 1307 | Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); |
sspitsyn@7636 | 1308 | |
sspitsyn@7636 | 1309 | assert(new_method != NULL, "method_with_idnum() should not be NULL"); |
sspitsyn@7636 | 1310 | assert(old_method != new_method, "sanity check"); |
sspitsyn@7636 | 1311 | |
sspitsyn@7636 | 1312 | ime->initialize(new_method); |
sspitsyn@7636 | 1313 | |
sspitsyn@7636 | 1314 | if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { |
sspitsyn@7636 | 1315 | if (!(*trace_name_printed)) { |
sspitsyn@7636 | 1316 | // RC_TRACE_MESG macro has an embedded ResourceMark |
sspitsyn@7636 | 1317 | RC_TRACE_MESG(("adjust: name=%s", |
sspitsyn@7636 | 1318 | old_method->method_holder()->external_name())); |
sspitsyn@7636 | 1319 | *trace_name_printed = true; |
duke@435 | 1320 | } |
sspitsyn@7636 | 1321 | // RC_TRACE macro has an embedded ResourceMark |
sspitsyn@7636 | 1322 | RC_TRACE(0x00200000, ("itable method update: %s(%s)", |
sspitsyn@7636 | 1323 | new_method->name()->as_C_string(), |
sspitsyn@7636 | 1324 | new_method->signature()->as_C_string())); |
duke@435 | 1325 | } |
duke@435 | 1326 | } |
duke@435 | 1327 | } |
duke@435 | 1328 | |
dcubed@4562 | 1329 | // an itable should never contain old or obsolete methods |
dcubed@4562 | 1330 | bool klassItable::check_no_old_or_obsolete_entries() { |
dcubed@4562 | 1331 | itableMethodEntry* ime = method_entry(0); |
dcubed@4562 | 1332 | for (int i = 0; i < _size_method_table; i++) { |
dcubed@4562 | 1333 | Method* m = ime->method(); |
dcubed@4562 | 1334 | if (m != NULL && |
dcubed@4562 | 1335 | (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) { |
dcubed@4562 | 1336 | return false; |
dcubed@4562 | 1337 | } |
dcubed@4562 | 1338 | ime++; |
dcubed@4562 | 1339 | } |
dcubed@4562 | 1340 | return true; |
dcubed@4562 | 1341 | } |
dcubed@4562 | 1342 | |
dcubed@4562 | 1343 | void klassItable::dump_itable() { |
dcubed@4562 | 1344 | itableMethodEntry* ime = method_entry(0); |
dcubed@4562 | 1345 | tty->print_cr("itable dump --"); |
dcubed@4562 | 1346 | for (int i = 0; i < _size_method_table; i++) { |
dcubed@4562 | 1347 | Method* m = ime->method(); |
dcubed@4562 | 1348 | if (m != NULL) { |
dcubed@4562 | 1349 | tty->print(" (%5d) ", i); |
dcubed@4562 | 1350 | m->access_flags().print_on(tty); |
acorn@5848 | 1351 | if (m->is_default_method()) { |
acorn@6080 | 1352 | tty->print("default "); |
acorn@5848 | 1353 | } |
dcubed@4562 | 1354 | tty->print(" -- "); |
dcubed@4562 | 1355 | m->print_name(tty); |
dcubed@4562 | 1356 | tty->cr(); |
dcubed@4562 | 1357 | } |
dcubed@4562 | 1358 | ime++; |
dcubed@4562 | 1359 | } |
dcubed@4562 | 1360 | } |
dcubed@4562 | 1361 | #endif // INCLUDE_JVMTI |
dcubed@4562 | 1362 | |
duke@435 | 1363 | // Setup |
duke@435 | 1364 | class InterfaceVisiterClosure : public StackObj { |
duke@435 | 1365 | public: |
coleenp@4037 | 1366 | virtual void doit(Klass* intf, int method_count) = 0; |
duke@435 | 1367 | }; |
duke@435 | 1368 | |
drchase@5732 | 1369 | // Visit all interfaces with at least one itable method |
coleenp@4037 | 1370 | void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosure *blk) { |
duke@435 | 1371 | // Handle array argument |
duke@435 | 1372 | for(int i = 0; i < transitive_intf->length(); i++) { |
coleenp@4037 | 1373 | Klass* intf = transitive_intf->at(i); |
hseigel@4278 | 1374 | assert(intf->is_interface(), "sanity check"); |
duke@435 | 1375 | |
drchase@5732 | 1376 | // Find no. of itable methods |
drchase@5732 | 1377 | int method_count = 0; |
drchase@5732 | 1378 | // method_count = klassItable::method_count_for_interface(intf); |
drchase@5732 | 1379 | Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); |
drchase@5732 | 1380 | if (methods->length() > 0) { |
drchase@5732 | 1381 | for (int i = methods->length(); --i >= 0; ) { |
drchase@5732 | 1382 | if (interface_method_needs_itable_index(methods->at(i))) { |
drchase@5732 | 1383 | method_count++; |
drchase@5732 | 1384 | } |
duke@435 | 1385 | } |
duke@435 | 1386 | } |
duke@435 | 1387 | |
dbuck@8997 | 1388 | // Visit all interfaces which either have any methods or can participate in receiver type check. |
dbuck@8997 | 1389 | // We do not bother to count methods in transitive interfaces, although that would allow us to skip |
dbuck@8997 | 1390 | // this step in the rare case of a zero-method interface extending another zero-method interface. |
dbuck@8997 | 1391 | if (method_count > 0 || InstanceKlass::cast(intf)->transitive_interfaces()->length() > 0) { |
duke@435 | 1392 | blk->doit(intf, method_count); |
duke@435 | 1393 | } |
duke@435 | 1394 | } |
duke@435 | 1395 | } |
duke@435 | 1396 | |
duke@435 | 1397 | class CountInterfacesClosure : public InterfaceVisiterClosure { |
duke@435 | 1398 | private: |
duke@435 | 1399 | int _nof_methods; |
duke@435 | 1400 | int _nof_interfaces; |
duke@435 | 1401 | public: |
duke@435 | 1402 | CountInterfacesClosure() { _nof_methods = 0; _nof_interfaces = 0; } |
duke@435 | 1403 | |
duke@435 | 1404 | int nof_methods() const { return _nof_methods; } |
duke@435 | 1405 | int nof_interfaces() const { return _nof_interfaces; } |
duke@435 | 1406 | |
coleenp@4037 | 1407 | void doit(Klass* intf, int method_count) { _nof_methods += method_count; _nof_interfaces++; } |
duke@435 | 1408 | }; |
duke@435 | 1409 | |
duke@435 | 1410 | class SetupItableClosure : public InterfaceVisiterClosure { |
duke@435 | 1411 | private: |
duke@435 | 1412 | itableOffsetEntry* _offset_entry; |
duke@435 | 1413 | itableMethodEntry* _method_entry; |
duke@435 | 1414 | address _klass_begin; |
duke@435 | 1415 | public: |
duke@435 | 1416 | SetupItableClosure(address klass_begin, itableOffsetEntry* offset_entry, itableMethodEntry* method_entry) { |
duke@435 | 1417 | _klass_begin = klass_begin; |
duke@435 | 1418 | _offset_entry = offset_entry; |
duke@435 | 1419 | _method_entry = method_entry; |
duke@435 | 1420 | } |
duke@435 | 1421 | |
duke@435 | 1422 | itableMethodEntry* method_entry() const { return _method_entry; } |
duke@435 | 1423 | |
coleenp@4037 | 1424 | void doit(Klass* intf, int method_count) { |
duke@435 | 1425 | int offset = ((address)_method_entry) - _klass_begin; |
duke@435 | 1426 | _offset_entry->initialize(intf, offset); |
duke@435 | 1427 | _offset_entry++; |
duke@435 | 1428 | _method_entry += method_count; |
duke@435 | 1429 | } |
duke@435 | 1430 | }; |
duke@435 | 1431 | |
coleenp@4037 | 1432 | int klassItable::compute_itable_size(Array<Klass*>* transitive_interfaces) { |
duke@435 | 1433 | // Count no of interfaces and total number of interface methods |
duke@435 | 1434 | CountInterfacesClosure cic; |
coleenp@4037 | 1435 | visit_all_interfaces(transitive_interfaces, &cic); |
duke@435 | 1436 | |
dcubed@451 | 1437 | // There's alway an extra itable entry so we can null-terminate it. |
dcubed@451 | 1438 | int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods()); |
duke@435 | 1439 | |
duke@435 | 1440 | // Statistics |
duke@435 | 1441 | update_stats(itable_size * HeapWordSize); |
duke@435 | 1442 | |
duke@435 | 1443 | return itable_size; |
duke@435 | 1444 | } |
duke@435 | 1445 | |
duke@435 | 1446 | |
duke@435 | 1447 | // Fill out offset table and interface klasses into the itable space |
duke@435 | 1448 | void klassItable::setup_itable_offset_table(instanceKlassHandle klass) { |
duke@435 | 1449 | if (klass->itable_length() == 0) return; |
duke@435 | 1450 | assert(!klass->is_interface(), "Should have zero length itable"); |
duke@435 | 1451 | |
duke@435 | 1452 | // Count no of interfaces and total number of interface methods |
duke@435 | 1453 | CountInterfacesClosure cic; |
duke@435 | 1454 | visit_all_interfaces(klass->transitive_interfaces(), &cic); |
duke@435 | 1455 | int nof_methods = cic.nof_methods(); |
duke@435 | 1456 | int nof_interfaces = cic.nof_interfaces(); |
duke@435 | 1457 | |
dcubed@451 | 1458 | // Add one extra entry so we can null-terminate the table |
dcubed@451 | 1459 | nof_interfaces++; |
duke@435 | 1460 | |
coleenp@4037 | 1461 | assert(compute_itable_size(klass->transitive_interfaces()) == |
duke@435 | 1462 | calc_itable_size(nof_interfaces, nof_methods), |
duke@435 | 1463 | "mismatch calculation of itable size"); |
duke@435 | 1464 | |
duke@435 | 1465 | // Fill-out offset table |
duke@435 | 1466 | itableOffsetEntry* ioe = (itableOffsetEntry*)klass->start_of_itable(); |
duke@435 | 1467 | itableMethodEntry* ime = (itableMethodEntry*)(ioe + nof_interfaces); |
duke@435 | 1468 | intptr_t* end = klass->end_of_itable(); |
never@2658 | 1469 | assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_nonstatic_oop_maps(), "wrong offset calculation (1)"); |
coleenp@548 | 1470 | assert((oop*)(end) == (oop*)(ime + nof_methods), "wrong offset calculation (2)"); |
duke@435 | 1471 | |
duke@435 | 1472 | // Visit all interfaces and initialize itable offset table |
coleenp@4037 | 1473 | SetupItableClosure sic((address)klass(), ioe, ime); |
duke@435 | 1474 | visit_all_interfaces(klass->transitive_interfaces(), &sic); |
duke@435 | 1475 | |
duke@435 | 1476 | #ifdef ASSERT |
duke@435 | 1477 | ime = sic.method_entry(); |
duke@435 | 1478 | oop* v = (oop*) klass->end_of_itable(); |
duke@435 | 1479 | assert( (oop*)(ime) == v, "wrong offset calculation (2)"); |
duke@435 | 1480 | #endif |
duke@435 | 1481 | } |
duke@435 | 1482 | |
duke@435 | 1483 | |
drchase@5732 | 1484 | // inverse to itable_index |
coleenp@4037 | 1485 | Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) { |
coleenp@4037 | 1486 | assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); |
drchase@5732 | 1487 | assert(intf->verify_itable_index(itable_index), ""); |
coleenp@4037 | 1488 | Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); |
jrose@1100 | 1489 | |
drchase@5732 | 1490 | if (itable_index < 0 || itable_index >= method_count_for_interface(intf)) |
acorn@5848 | 1491 | return NULL; // help caller defend against bad indices |
jrose@1100 | 1492 | |
drchase@5732 | 1493 | int index = itable_index; |
coleenp@4037 | 1494 | Method* m = methods->at(index); |
drchase@5732 | 1495 | int index2 = -1; |
drchase@5732 | 1496 | while (!m->has_itable_index() || |
drchase@5732 | 1497 | (index2 = m->itable_index()) != itable_index) { |
drchase@5732 | 1498 | assert(index2 < itable_index, "monotonic"); |
drchase@5732 | 1499 | if (++index == methods->length()) |
drchase@5732 | 1500 | return NULL; |
drchase@5732 | 1501 | m = methods->at(index); |
drchase@5732 | 1502 | } |
drchase@5732 | 1503 | assert(m->itable_index() == itable_index, "correct inverse"); |
jrose@1100 | 1504 | |
jrose@1100 | 1505 | return m; |
jrose@1100 | 1506 | } |
jrose@1100 | 1507 | |
duke@435 | 1508 | void klassVtable::verify(outputStream* st, bool forced) { |
duke@435 | 1509 | // make sure table is initialized |
duke@435 | 1510 | if (!Universe::is_fully_initialized()) return; |
duke@435 | 1511 | #ifndef PRODUCT |
duke@435 | 1512 | // avoid redundant verifies |
duke@435 | 1513 | if (!forced && _verify_count == Universe::verify_count()) return; |
duke@435 | 1514 | _verify_count = Universe::verify_count(); |
duke@435 | 1515 | #endif |
duke@435 | 1516 | oop* end_of_obj = (oop*)_klass() + _klass()->size(); |
duke@435 | 1517 | oop* end_of_vtable = (oop *)&table()[_length]; |
duke@435 | 1518 | if (end_of_vtable > end_of_obj) { |
jcoomes@1845 | 1519 | fatal(err_msg("klass %s: klass object too short (vtable extends beyond " |
jcoomes@1845 | 1520 | "end)", _klass->internal_name())); |
duke@435 | 1521 | } |
duke@435 | 1522 | |
duke@435 | 1523 | for (int i = 0; i < _length; i++) table()[i].verify(this, st); |
duke@435 | 1524 | // verify consistency with superKlass vtable |
coleenp@4037 | 1525 | Klass* super = _klass->super(); |
duke@435 | 1526 | if (super != NULL) { |
coleenp@4037 | 1527 | InstanceKlass* sk = InstanceKlass::cast(super); |
duke@435 | 1528 | klassVtable* vt = sk->vtable(); |
duke@435 | 1529 | for (int i = 0; i < vt->length(); i++) { |
duke@435 | 1530 | verify_against(st, vt, i); |
duke@435 | 1531 | } |
duke@435 | 1532 | } |
duke@435 | 1533 | } |
duke@435 | 1534 | |
duke@435 | 1535 | void klassVtable::verify_against(outputStream* st, klassVtable* vt, int index) { |
duke@435 | 1536 | vtableEntry* vte = &vt->table()[index]; |
duke@435 | 1537 | if (vte->method()->name() != table()[index].method()->name() || |
duke@435 | 1538 | vte->method()->signature() != table()[index].method()->signature()) { |
duke@435 | 1539 | fatal("mismatched name/signature of vtable entries"); |
duke@435 | 1540 | } |
duke@435 | 1541 | } |
duke@435 | 1542 | |
duke@435 | 1543 | #ifndef PRODUCT |
duke@435 | 1544 | void klassVtable::print() { |
duke@435 | 1545 | ResourceMark rm; |
duke@435 | 1546 | tty->print("klassVtable for klass %s (length %d):\n", _klass->internal_name(), length()); |
duke@435 | 1547 | for (int i = 0; i < length(); i++) { |
duke@435 | 1548 | table()[i].print(); |
duke@435 | 1549 | tty->cr(); |
duke@435 | 1550 | } |
duke@435 | 1551 | } |
duke@435 | 1552 | #endif |
duke@435 | 1553 | |
duke@435 | 1554 | void vtableEntry::verify(klassVtable* vt, outputStream* st) { |
duke@435 | 1555 | NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true)); |
duke@435 | 1556 | assert(method() != NULL, "must have set method"); |
duke@435 | 1557 | method()->verify(); |
duke@435 | 1558 | // we sub_type, because it could be a miranda method |
duke@435 | 1559 | if (!vt->klass()->is_subtype_of(method()->method_holder())) { |
duke@435 | 1560 | #ifndef PRODUCT |
duke@435 | 1561 | print(); |
duke@435 | 1562 | #endif |
jcoomes@1845 | 1563 | fatal(err_msg("vtableEntry " PTR_FORMAT ": method is from subclass", this)); |
duke@435 | 1564 | } |
duke@435 | 1565 | } |
duke@435 | 1566 | |
duke@435 | 1567 | #ifndef PRODUCT |
duke@435 | 1568 | |
duke@435 | 1569 | void vtableEntry::print() { |
duke@435 | 1570 | ResourceMark rm; |
duke@435 | 1571 | tty->print("vtableEntry %s: ", method()->name()->as_C_string()); |
duke@435 | 1572 | if (Verbose) { |
duke@435 | 1573 | tty->print("m %#lx ", (address)method()); |
duke@435 | 1574 | } |
duke@435 | 1575 | } |
duke@435 | 1576 | |
duke@435 | 1577 | class VtableStats : AllStatic { |
duke@435 | 1578 | public: |
duke@435 | 1579 | static int no_klasses; // # classes with vtables |
duke@435 | 1580 | static int no_array_klasses; // # array classes |
duke@435 | 1581 | static int no_instance_klasses; // # instanceKlasses |
duke@435 | 1582 | static int sum_of_vtable_len; // total # of vtable entries |
duke@435 | 1583 | static int sum_of_array_vtable_len; // total # of vtable entries in array klasses only |
duke@435 | 1584 | static int fixed; // total fixed overhead in bytes |
duke@435 | 1585 | static int filler; // overhead caused by filler bytes |
duke@435 | 1586 | static int entries; // total bytes consumed by vtable entries |
duke@435 | 1587 | static int array_entries; // total bytes consumed by array vtable entries |
duke@435 | 1588 | |
coleenp@4037 | 1589 | static void do_class(Klass* k) { |
coleenp@4037 | 1590 | Klass* kl = k; |
duke@435 | 1591 | klassVtable* vt = kl->vtable(); |
duke@435 | 1592 | if (vt == NULL) return; |
duke@435 | 1593 | no_klasses++; |
duke@435 | 1594 | if (kl->oop_is_instance()) { |
duke@435 | 1595 | no_instance_klasses++; |
duke@435 | 1596 | kl->array_klasses_do(do_class); |
duke@435 | 1597 | } |
duke@435 | 1598 | if (kl->oop_is_array()) { |
duke@435 | 1599 | no_array_klasses++; |
duke@435 | 1600 | sum_of_array_vtable_len += vt->length(); |
duke@435 | 1601 | } |
duke@435 | 1602 | sum_of_vtable_len += vt->length(); |
duke@435 | 1603 | } |
duke@435 | 1604 | |
duke@435 | 1605 | static void compute() { |
duke@435 | 1606 | SystemDictionary::classes_do(do_class); |
duke@435 | 1607 | fixed = no_klasses * oopSize; // vtable length |
duke@435 | 1608 | // filler size is a conservative approximation |
coleenp@4142 | 1609 | filler = oopSize * (no_klasses - no_instance_klasses) * (sizeof(InstanceKlass) - sizeof(ArrayKlass) - 1); |
duke@435 | 1610 | entries = sizeof(vtableEntry) * sum_of_vtable_len; |
duke@435 | 1611 | array_entries = sizeof(vtableEntry) * sum_of_array_vtable_len; |
duke@435 | 1612 | } |
duke@435 | 1613 | }; |
duke@435 | 1614 | |
duke@435 | 1615 | int VtableStats::no_klasses = 0; |
duke@435 | 1616 | int VtableStats::no_array_klasses = 0; |
duke@435 | 1617 | int VtableStats::no_instance_klasses = 0; |
duke@435 | 1618 | int VtableStats::sum_of_vtable_len = 0; |
duke@435 | 1619 | int VtableStats::sum_of_array_vtable_len = 0; |
duke@435 | 1620 | int VtableStats::fixed = 0; |
duke@435 | 1621 | int VtableStats::filler = 0; |
duke@435 | 1622 | int VtableStats::entries = 0; |
duke@435 | 1623 | int VtableStats::array_entries = 0; |
duke@435 | 1624 | |
duke@435 | 1625 | void klassVtable::print_statistics() { |
duke@435 | 1626 | ResourceMark rm; |
duke@435 | 1627 | HandleMark hm; |
duke@435 | 1628 | VtableStats::compute(); |
duke@435 | 1629 | tty->print_cr("vtable statistics:"); |
duke@435 | 1630 | tty->print_cr("%6d classes (%d instance, %d array)", VtableStats::no_klasses, VtableStats::no_instance_klasses, VtableStats::no_array_klasses); |
duke@435 | 1631 | int total = VtableStats::fixed + VtableStats::filler + VtableStats::entries; |
duke@435 | 1632 | tty->print_cr("%6d bytes fixed overhead (refs + vtable object header)", VtableStats::fixed); |
duke@435 | 1633 | tty->print_cr("%6d bytes filler overhead", VtableStats::filler); |
duke@435 | 1634 | tty->print_cr("%6d bytes for vtable entries (%d for arrays)", VtableStats::entries, VtableStats::array_entries); |
duke@435 | 1635 | tty->print_cr("%6d bytes total", total); |
duke@435 | 1636 | } |
duke@435 | 1637 | |
duke@435 | 1638 | int klassItable::_total_classes; // Total no. of classes with itables |
duke@435 | 1639 | long klassItable::_total_size; // Total no. of bytes used for itables |
duke@435 | 1640 | |
duke@435 | 1641 | void klassItable::print_statistics() { |
duke@435 | 1642 | tty->print_cr("itable statistics:"); |
duke@435 | 1643 | tty->print_cr("%6d classes with itables", _total_classes); |
duke@435 | 1644 | tty->print_cr("%6d K uses for itables (average by class: %d bytes)", _total_size / K, _total_size / _total_classes); |
duke@435 | 1645 | } |
duke@435 | 1646 | |
duke@435 | 1647 | #endif // PRODUCT |