src/share/vm/oops/klassVtable.cpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2658
c7f3d0b4570f
child 2777
8ce625481709
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
stefank@2534 2 * Copyright (c) 1997, 2011, 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"
stefank@2314 30 #include "memory/resourceArea.hpp"
stefank@2314 31 #include "memory/universe.inline.hpp"
stefank@2314 32 #include "oops/instanceKlass.hpp"
stefank@2314 33 #include "oops/klassOop.hpp"
stefank@2314 34 #include "oops/klassVtable.hpp"
stefank@2314 35 #include "oops/methodOop.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
duke@435 43 inline instanceKlass* klassVtable::ik() const {
duke@435 44 Klass* k = _klass()->klass_part();
duke@435 45 assert(k->oop_is_instance(), "not an instanceKlass");
duke@435 46 return (instanceKlass*)k;
duke@435 47 }
duke@435 48
duke@435 49
duke@435 50 // this function computes the vtable size (including the size needed for miranda
duke@435 51 // methods) and the number of miranda methods in this class
duke@435 52 // Note on Miranda methods: Let's say there is a class C that implements
duke@435 53 // interface I. Let's say there is a method m in I that neither C nor any
duke@435 54 // of its super classes implement (i.e there is no method of any access, with
duke@435 55 // the same name and signature as m), then m is a Miranda method which is
duke@435 56 // entered as a public abstract method in C's vtable. From then on it should
duke@435 57 // treated as any other public method in C for method over-ride purposes.
duke@435 58 void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
duke@435 59 int &num_miranda_methods,
duke@435 60 klassOop super,
duke@435 61 objArrayOop methods,
duke@435 62 AccessFlags class_flags,
acorn@1087 63 Handle classloader,
coleenp@2497 64 Symbol* classname,
acorn@1087 65 objArrayOop local_interfaces,
acorn@1087 66 TRAPS
duke@435 67 ) {
duke@435 68
duke@435 69 No_Safepoint_Verifier nsv;
duke@435 70
duke@435 71 // set up default result values
duke@435 72 vtable_length = 0;
duke@435 73 num_miranda_methods = 0;
duke@435 74
duke@435 75 // start off with super's vtable length
duke@435 76 instanceKlass* sk = (instanceKlass*)super->klass_part();
duke@435 77 vtable_length = super == NULL ? 0 : sk->vtable_length();
duke@435 78
duke@435 79 // go thru each method in the methods table to see if it needs a new entry
duke@435 80 int len = methods->length();
duke@435 81 for (int i = 0; i < len; i++) {
duke@435 82 assert(methods->obj_at(i)->is_method(), "must be a methodOop");
acorn@1087 83 methodHandle mh(THREAD, methodOop(methods->obj_at(i)));
duke@435 84
acorn@1087 85 if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) {
duke@435 86 vtable_length += vtableEntry::size(); // we need a new entry
duke@435 87 }
duke@435 88 }
duke@435 89
duke@435 90 // compute the number of mirandas methods that must be added to the end
duke@435 91 num_miranda_methods = get_num_mirandas(super, methods, local_interfaces);
duke@435 92 vtable_length += (num_miranda_methods * vtableEntry::size());
duke@435 93
duke@435 94 if (Universe::is_bootstrapping() && vtable_length == 0) {
duke@435 95 // array classes don't have their superclass set correctly during
duke@435 96 // bootstrapping
duke@435 97 vtable_length = Universe::base_vtable_size();
duke@435 98 }
duke@435 99
duke@435 100 if (super == NULL && !Universe::is_bootstrapping() &&
duke@435 101 vtable_length != Universe::base_vtable_size()) {
duke@435 102 // Someone is attempting to redefine java.lang.Object incorrectly. The
duke@435 103 // only way this should happen is from
duke@435 104 // SystemDictionary::resolve_from_stream(), which will detect this later
duke@435 105 // and throw a security exception. So don't assert here to let
duke@435 106 // the exception occur.
duke@435 107 vtable_length = Universe::base_vtable_size();
duke@435 108 }
duke@435 109 assert(super != NULL || vtable_length == Universe::base_vtable_size(),
duke@435 110 "bad vtable size for class Object");
duke@435 111 assert(vtable_length % vtableEntry::size() == 0, "bad vtable length");
duke@435 112 assert(vtable_length >= Universe::base_vtable_size(), "vtable too small");
duke@435 113 }
duke@435 114
duke@435 115 int klassVtable::index_of(methodOop m, int len) const {
duke@435 116 assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods");
duke@435 117 return m->vtable_index();
duke@435 118 }
duke@435 119
duke@435 120 int klassVtable::initialize_from_super(KlassHandle super) {
duke@435 121 if (super.is_null()) {
duke@435 122 return 0;
duke@435 123 } else {
duke@435 124 // copy methods from superKlass
duke@435 125 // can't inherit from array class, so must be instanceKlass
duke@435 126 assert(super->oop_is_instance(), "must be instance klass");
duke@435 127 instanceKlass* sk = (instanceKlass*)super()->klass_part();
duke@435 128 klassVtable* superVtable = sk->vtable();
duke@435 129 assert(superVtable->length() <= _length, "vtable too short");
duke@435 130 #ifdef ASSERT
duke@435 131 superVtable->verify(tty, true);
duke@435 132 #endif
duke@435 133 superVtable->copy_vtable_to(table());
duke@435 134 #ifndef PRODUCT
duke@435 135 if (PrintVtables && Verbose) {
acorn@1087 136 ResourceMark rm;
duke@435 137 tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length);
duke@435 138 }
duke@435 139 #endif
duke@435 140 return superVtable->length();
duke@435 141 }
duke@435 142 }
duke@435 143
duke@435 144 // Revised lookup semantics introduced 1.3 (Kestral beta)
duke@435 145 void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
duke@435 146
duke@435 147 // Note: Arrays can have intermediate array supers. Use java_super to skip them.
duke@435 148 KlassHandle super (THREAD, klass()->java_super());
duke@435 149 int nofNewEntries = 0;
duke@435 150
duke@435 151
duke@435 152 if (PrintVtables && !klass()->oop_is_array()) {
duke@435 153 ResourceMark rm(THREAD);
duke@435 154 tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
duke@435 155 }
duke@435 156
duke@435 157 #ifdef ASSERT
duke@435 158 oop* end_of_obj = (oop*)_klass() + _klass()->size();
duke@435 159 oop* end_of_vtable = (oop*)&table()[_length];
duke@435 160 assert(end_of_vtable <= end_of_obj, "vtable extends beyond end");
duke@435 161 #endif
duke@435 162
duke@435 163 if (Universe::is_bootstrapping()) {
duke@435 164 // just clear everything
duke@435 165 for (int i = 0; i < _length; i++) table()[i].clear();
duke@435 166 return;
duke@435 167 }
duke@435 168
duke@435 169 int super_vtable_len = initialize_from_super(super);
duke@435 170 if (klass()->oop_is_array()) {
duke@435 171 assert(super_vtable_len == _length, "arrays shouldn't introduce new methods");
duke@435 172 } else {
duke@435 173 assert(_klass->oop_is_instance(), "must be instanceKlass");
duke@435 174
duke@435 175 objArrayHandle methods(THREAD, ik()->methods());
duke@435 176 int len = methods()->length();
duke@435 177 int initialized = super_vtable_len;
duke@435 178
acorn@1087 179 // update_inherited_vtable can stop for gc - ensure using handles
duke@435 180 for (int i = 0; i < len; i++) {
duke@435 181 HandleMark hm(THREAD);
duke@435 182 assert(methods()->obj_at(i)->is_method(), "must be a methodOop");
duke@435 183 methodHandle mh(THREAD, (methodOop)methods()->obj_at(i));
duke@435 184
acorn@1087 185 bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK);
duke@435 186
duke@435 187 if (needs_new_entry) {
duke@435 188 put_method_at(mh(), initialized);
duke@435 189 mh()->set_vtable_index(initialized); // set primary vtable index
duke@435 190 initialized++;
duke@435 191 }
duke@435 192 }
duke@435 193
duke@435 194 // add miranda methods; it will also update the value of initialized
duke@435 195 fill_in_mirandas(initialized);
duke@435 196
acorn@1087 197 // In class hierarchies where the accessibility is not increasing (i.e., going from private ->
duke@435 198 // package_private -> publicprotected), the vtable might actually be smaller than our initial
duke@435 199 // calculation.
duke@435 200 assert(initialized <= _length, "vtable initialization failed");
duke@435 201 for(;initialized < _length; initialized++) {
duke@435 202 put_method_at(NULL, initialized);
duke@435 203 }
duke@435 204 NOT_PRODUCT(verify(tty, true));
duke@435 205 }
duke@435 206 }
duke@435 207
acorn@1087 208 // Called for cases where a method does not override its superclass' vtable entry
acorn@1087 209 // For bytecodes not produced by javac together it is possible that a method does not override
acorn@1087 210 // the superclass's method, but might indirectly override a super-super class's vtable entry
acorn@1087 211 // If none found, return a null superk, else return the superk of the method this does override
acorn@1087 212 instanceKlass* klassVtable::find_transitive_override(instanceKlass* initialsuper, methodHandle target_method,
coleenp@2497 213 int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
acorn@1087 214 instanceKlass* superk = initialsuper;
acorn@1087 215 while (superk != NULL && superk->super() != NULL) {
acorn@1087 216 instanceKlass* supersuperklass = instanceKlass::cast(superk->super());
acorn@1087 217 klassVtable* ssVtable = supersuperklass->vtable();
acorn@1087 218 if (vtable_index < ssVtable->length()) {
acorn@1087 219 methodOop super_method = ssVtable->method_at(vtable_index);
acorn@1087 220 #ifndef PRODUCT
coleenp@2497 221 Symbol* name= target_method()->name();
coleenp@2497 222 Symbol* signature = target_method()->signature();
coleenp@2497 223 assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch");
acorn@1087 224 #endif
acorn@1087 225 if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) {
acorn@1087 226 #ifndef PRODUCT
acorn@1087 227 if (PrintVtables && Verbose) {
acorn@1087 228 ResourceMark rm(THREAD);
acorn@1087 229 tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ",
acorn@1087 230 supersuperklass->internal_name(),
acorn@1087 231 _klass->internal_name(), (target_method() != NULL) ?
acorn@1087 232 target_method()->name()->as_C_string() : "<NULL>", vtable_index);
acorn@1087 233 super_method->access_flags().print_on(tty);
acorn@1087 234 tty->print("overriders flags: ");
acorn@1087 235 target_method->access_flags().print_on(tty);
acorn@1087 236 tty->cr();
acorn@1087 237 }
acorn@1087 238 #endif /*PRODUCT*/
acorn@1087 239 break; // return found superk
acorn@1087 240 }
acorn@1087 241 } else {
acorn@1087 242 // super class has no vtable entry here, stop transitive search
acorn@1087 243 superk = (instanceKlass*)NULL;
acorn@1087 244 break;
acorn@1087 245 }
acorn@1087 246 // if no override found yet, continue to search up
acorn@1087 247 superk = instanceKlass::cast(superk->super());
acorn@1087 248 }
duke@435 249
acorn@1087 250 return superk;
duke@435 251 }
duke@435 252
duke@435 253
duke@435 254 // Update child's copy of super vtable for overrides
duke@435 255 // OR return true if a new vtable entry is required
duke@435 256 // Only called for instanceKlass's, i.e. not for arrays
duke@435 257 // If that changed, could not use _klass as handle for klass
acorn@1087 258 bool klassVtable::update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len,
acorn@1087 259 bool checkconstraints, TRAPS) {
duke@435 260 ResourceMark rm;
duke@435 261 bool allocate_new = true;
duke@435 262 assert(klass->oop_is_instance(), "must be instanceKlass");
duke@435 263
duke@435 264 // Initialize the method's vtable index to "nonvirtual".
duke@435 265 // If we allocate a vtable entry, we will update it to a non-negative number.
duke@435 266 target_method()->set_vtable_index(methodOopDesc::nonvirtual_vtable_index);
duke@435 267
duke@435 268 // Static and <init> methods are never in
duke@435 269 if (target_method()->is_static() || target_method()->name() == vmSymbols::object_initializer_name()) {
duke@435 270 return false;
duke@435 271 }
duke@435 272
duke@435 273 if (klass->is_final() || target_method()->is_final()) {
duke@435 274 // a final method never needs a new entry; final methods can be statically
duke@435 275 // resolved and they have to be present in the vtable only if they override
duke@435 276 // a super's method, in which case they re-use its entry
duke@435 277 allocate_new = false;
duke@435 278 }
duke@435 279
duke@435 280 // we need a new entry if there is no superclass
duke@435 281 if (klass->super() == NULL) {
duke@435 282 return allocate_new;
duke@435 283 }
duke@435 284
duke@435 285 // private methods always have a new entry in the vtable
acorn@1087 286 // specification interpretation since classic has
acorn@1087 287 // private methods not overriding
duke@435 288 if (target_method()->is_private()) {
duke@435 289 return allocate_new;
duke@435 290 }
duke@435 291
duke@435 292 // search through the vtable and update overridden entries
duke@435 293 // Since check_signature_loaders acquires SystemDictionary_lock
acorn@1087 294 // which can block for gc, once we are in this loop, use handles
acorn@1087 295 // For classfiles built with >= jdk7, we now look for transitive overrides
duke@435 296
coleenp@2497 297 Symbol* name = target_method()->name();
coleenp@2497 298 Symbol* signature = target_method()->signature();
acorn@1087 299 Handle target_loader(THREAD, _klass->class_loader());
coleenp@2497 300 Symbol* target_classname = _klass->name();
duke@435 301 for(int i = 0; i < super_vtable_len; i++) {
acorn@1087 302 methodOop super_method = method_at(i);
duke@435 303 // Check if method name matches
coleenp@2497 304 if (super_method->name() == name && super_method->signature() == signature) {
duke@435 305
acorn@1087 306 // get super_klass for method_holder for the found method
acorn@1087 307 instanceKlass* super_klass = instanceKlass::cast(super_method->method_holder());
duke@435 308
acorn@1087 309 if ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) ||
acorn@1087 310 ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
acorn@1087 311 && ((super_klass = find_transitive_override(super_klass, target_method, i, target_loader,
acorn@1087 312 target_classname, THREAD)) != (instanceKlass*)NULL))) {
acorn@1087 313 // overriding, so no new entry
acorn@1087 314 allocate_new = false;
duke@435 315
duke@435 316 if (checkconstraints) {
duke@435 317 // Override vtable entry if passes loader constraint check
duke@435 318 // if loader constraint checking requested
duke@435 319 // No need to visit his super, since he and his super
duke@435 320 // have already made any needed loader constraints.
duke@435 321 // Since loader constraints are transitive, it is enough
duke@435 322 // to link to the first super, and we get all the others.
duke@435 323 Handle super_loader(THREAD, super_klass->class_loader());
duke@435 324
acorn@1087 325 if (target_loader() != super_loader()) {
duke@435 326 ResourceMark rm(THREAD);
duke@435 327 char* failed_type_name =
acorn@1087 328 SystemDictionary::check_signature_loaders(signature, target_loader,
duke@435 329 super_loader, true,
duke@435 330 CHECK_(false));
duke@435 331 if (failed_type_name != NULL) {
duke@435 332 const char* msg = "loader constraint violation: when resolving "
duke@435 333 "overridden method \"%s\" the class loader (instance"
duke@435 334 " of %s) of the current class, %s, and its superclass loader "
duke@435 335 "(instance of %s), have different Class objects for the type "
duke@435 336 "%s used in the signature";
duke@435 337 char* sig = target_method()->name_and_sig_as_C_string();
acorn@1087 338 const char* loader1 = SystemDictionary::loader_name(target_loader());
duke@435 339 char* current = _klass->name()->as_C_string();
duke@435 340 const char* loader2 = SystemDictionary::loader_name(super_loader());
duke@435 341 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
duke@435 342 strlen(current) + strlen(loader2) + strlen(failed_type_name);
duke@435 343 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
duke@435 344 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
duke@435 345 failed_type_name);
duke@435 346 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false);
duke@435 347 }
duke@435 348 }
acorn@1087 349 }
acorn@1087 350
acorn@1087 351 put_method_at(target_method(), i);
acorn@1087 352 target_method()->set_vtable_index(i);
acorn@1087 353 #ifndef PRODUCT
acorn@1087 354 if (PrintVtables && Verbose) {
acorn@1087 355 tty->print("overriding with %s::%s index %d, original flags: ",
acorn@1087 356 _klass->internal_name(), (target_method() != NULL) ?
acorn@1087 357 target_method()->name()->as_C_string() : "<NULL>", i);
acorn@1087 358 super_method->access_flags().print_on(tty);
acorn@1087 359 tty->print("overriders flags: ");
acorn@1087 360 target_method->access_flags().print_on(tty);
acorn@1087 361 tty->cr();
duke@435 362 }
acorn@1087 363 #endif /*PRODUCT*/
acorn@1087 364 } else {
acorn@1087 365 // allocate_new = true; default. We might override one entry,
acorn@1087 366 // but not override another. Once we override one, not need new
duke@435 367 #ifndef PRODUCT
acorn@1087 368 if (PrintVtables && Verbose) {
acorn@1087 369 tty->print("NOT overriding with %s::%s index %d, original flags: ",
acorn@1087 370 _klass->internal_name(), (target_method() != NULL) ?
acorn@1087 371 target_method()->name()->as_C_string() : "<NULL>", i);
acorn@1087 372 super_method->access_flags().print_on(tty);
acorn@1087 373 tty->print("overriders flags: ");
acorn@1087 374 target_method->access_flags().print_on(tty);
acorn@1087 375 tty->cr();
acorn@1087 376 }
duke@435 377 #endif /*PRODUCT*/
duke@435 378 }
duke@435 379 }
duke@435 380 }
duke@435 381 return allocate_new;
duke@435 382 }
duke@435 383
duke@435 384 void klassVtable::put_method_at(methodOop m, int index) {
duke@435 385 assert(m->is_oop_or_null(), "Not an oop or null");
duke@435 386 #ifndef PRODUCT
duke@435 387 if (PrintVtables && Verbose) {
acorn@1087 388 ResourceMark rm;
duke@435 389 tty->print_cr("adding %s::%s at index %d", _klass->internal_name(),
duke@435 390 (m != NULL) ? m->name()->as_C_string() : "<NULL>", index);
duke@435 391 }
duke@435 392 assert(unchecked_method_at(index)->is_oop_or_null(), "Not an oop or null");
duke@435 393 #endif
duke@435 394 table()[index].set(m);
duke@435 395 }
duke@435 396
duke@435 397 // Find out if a method "m" with superclass "super", loader "classloader" and
duke@435 398 // name "classname" needs a new vtable entry. Let P be a class package defined
duke@435 399 // by "classloader" and "classname".
duke@435 400 // NOTE: The logic used here is very similar to the one used for computing
duke@435 401 // the vtables indices for a method. We cannot directly use that function because,
acorn@1087 402 // we allocate the instanceKlass at load time, and that requires that the
acorn@1087 403 // superclass has been loaded.
acorn@1087 404 // However, the vtable entries are filled in at link time, and therefore
acorn@1087 405 // the superclass' vtable may not yet have been filled in.
acorn@1087 406 bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
duke@435 407 klassOop super,
acorn@1087 408 Handle classloader,
coleenp@2497 409 Symbol* classname,
acorn@1087 410 AccessFlags class_flags,
acorn@1087 411 TRAPS) {
acorn@1087 412 if ((class_flags.is_final() || target_method()->is_final()) ||
duke@435 413 // a final method never needs a new entry; final methods can be statically
duke@435 414 // resolved and they have to be present in the vtable only if they override
duke@435 415 // a super's method, in which case they re-use its entry
acorn@1087 416 (target_method()->is_static()) ||
duke@435 417 // static methods don't need to be in vtable
acorn@1087 418 (target_method()->name() == vmSymbols::object_initializer_name())
duke@435 419 // <init> is never called dynamically-bound
duke@435 420 ) {
duke@435 421 return false;
duke@435 422 }
duke@435 423
duke@435 424 // we need a new entry if there is no superclass
duke@435 425 if (super == NULL) {
duke@435 426 return true;
duke@435 427 }
duke@435 428
duke@435 429 // private methods always have a new entry in the vtable
acorn@1087 430 // specification interpretation since classic has
acorn@1087 431 // private methods not overriding
acorn@1087 432 if (target_method()->is_private()) {
duke@435 433 return true;
duke@435 434 }
duke@435 435
duke@435 436 // search through the super class hierarchy to see if we need
duke@435 437 // a new entry
acorn@1087 438 ResourceMark rm;
coleenp@2497 439 Symbol* name = target_method()->name();
coleenp@2497 440 Symbol* signature = target_method()->signature();
duke@435 441 klassOop k = super;
acorn@1087 442 methodOop super_method = NULL;
duke@435 443 instanceKlass *holder = NULL;
acorn@1087 444 methodOop recheck_method = NULL;
duke@435 445 while (k != NULL) {
duke@435 446 // lookup through the hierarchy for a method with matching name and sign.
acorn@1087 447 super_method = instanceKlass::cast(k)->lookup_method(name, signature);
acorn@1087 448 if (super_method == NULL) {
duke@435 449 break; // we still have to search for a matching miranda method
duke@435 450 }
duke@435 451 // get the class holding the matching method
acorn@1087 452 // make sure you use that class for is_override
acorn@1087 453 instanceKlass* superk = instanceKlass::cast(super_method->method_holder());
acorn@1087 454 // we want only instance method matches
acorn@1087 455 // pretend private methods are not in the super vtable
acorn@1087 456 // since we do override around them: e.g. a.m pub/b.m private/c.m pub,
acorn@1087 457 // ignore private, c.m pub does override a.m pub
acorn@1087 458 // For classes that were not javac'd together, we also do transitive overriding around
acorn@1087 459 // methods that have less accessibility
acorn@1087 460 if ((!super_method->is_static()) &&
acorn@1087 461 (!super_method->is_private())) {
acorn@1087 462 if (superk->is_override(super_method, classloader, classname, THREAD)) {
duke@435 463 return false;
acorn@1087 464 // else keep looking for transitive overrides
duke@435 465 }
duke@435 466 }
duke@435 467
acorn@1087 468 // Start with lookup result and continue to search up
acorn@1087 469 k = superk->super(); // haven't found an override match yet; continue to look
duke@435 470 }
duke@435 471
duke@435 472 // if the target method is public or protected it may have a matching
duke@435 473 // miranda method in the super, whose entry it should re-use.
acorn@1087 474 // Actually, to handle cases that javac would not generate, we need
acorn@1087 475 // this check for all access permissions.
acorn@1087 476 instanceKlass *sk = instanceKlass::cast(super);
acorn@1087 477 if (sk->has_miranda_methods()) {
acorn@1087 478 if (sk->lookup_method_in_all_interfaces(name, signature) != NULL) {
acorn@1087 479 return false; // found a matching miranda; we do not need a new entry
duke@435 480 }
duke@435 481 }
duke@435 482 return true; // found no match; we need a new entry
duke@435 483 }
duke@435 484
duke@435 485 // Support for miranda methods
duke@435 486
duke@435 487 // get the vtable index of a miranda method with matching "name" and "signature"
coleenp@2497 488 int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) {
duke@435 489 // search from the bottom, might be faster
duke@435 490 for (int i = (length() - 1); i >= 0; i--) {
duke@435 491 methodOop m = table()[i].method();
duke@435 492 if (is_miranda_entry_at(i) &&
duke@435 493 m->name() == name && m->signature() == signature) {
duke@435 494 return i;
duke@435 495 }
duke@435 496 }
duke@435 497 return methodOopDesc::invalid_vtable_index;
duke@435 498 }
duke@435 499
duke@435 500 // check if an entry is miranda
duke@435 501 bool klassVtable::is_miranda_entry_at(int i) {
duke@435 502 methodOop m = method_at(i);
duke@435 503 klassOop method_holder = m->method_holder();
duke@435 504 instanceKlass *mhk = instanceKlass::cast(method_holder);
duke@435 505
duke@435 506 // miranda methods are interface methods in a class's vtable
duke@435 507 if (mhk->is_interface()) {
duke@435 508 assert(m->is_public() && m->is_abstract(), "should be public and abstract");
duke@435 509 assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
duke@435 510 assert(is_miranda(m, ik()->methods(), ik()->super()), "should be a miranda_method");
duke@435 511 return true;
duke@435 512 }
duke@435 513 return false;
duke@435 514 }
duke@435 515
duke@435 516 // check if a method is a miranda method, given a class's methods table and it's super
duke@435 517 // the caller must make sure that the method belongs to an interface implemented by the class
duke@435 518 bool klassVtable::is_miranda(methodOop m, objArrayOop class_methods, klassOop super) {
coleenp@2497 519 Symbol* name = m->name();
coleenp@2497 520 Symbol* signature = m->signature();
duke@435 521 if (instanceKlass::find_method(class_methods, name, signature) == NULL) {
dsamersoff@2360 522 // did not find it in the method table of the current class
duke@435 523 if (super == NULL) {
duke@435 524 // super doesn't exist
duke@435 525 return true;
dsamersoff@2360 526 }
dsamersoff@2360 527
dsamersoff@2360 528 methodOop mo = instanceKlass::cast(super)->lookup_method(name, signature);
dsamersoff@2360 529 if (mo == NULL || mo->access_flags().is_private() ) {
dsamersoff@2360 530 // super class hierarchy does not implement it or protection is different
dsamersoff@2360 531 return true;
duke@435 532 }
duke@435 533 }
dsamersoff@2360 534
duke@435 535 return false;
duke@435 536 }
duke@435 537
duke@435 538 void klassVtable::add_new_mirandas_to_list(GrowableArray<methodOop>* list_of_current_mirandas,
duke@435 539 objArrayOop current_interface_methods,
duke@435 540 objArrayOop class_methods,
duke@435 541 klassOop super) {
duke@435 542 // iterate thru the current interface's method to see if it a miranda
duke@435 543 int num_methods = current_interface_methods->length();
duke@435 544 for (int i = 0; i < num_methods; i++) {
duke@435 545 methodOop im = methodOop(current_interface_methods->obj_at(i));
duke@435 546 bool is_duplicate = false;
duke@435 547 int num_of_current_mirandas = list_of_current_mirandas->length();
duke@435 548 // check for duplicate mirandas in different interfaces we implement
duke@435 549 for (int j = 0; j < num_of_current_mirandas; j++) {
duke@435 550 methodOop miranda = list_of_current_mirandas->at(j);
duke@435 551 if ((im->name() == miranda->name()) &&
duke@435 552 (im->signature() == miranda->signature())) {
duke@435 553 is_duplicate = true;
duke@435 554 break;
duke@435 555 }
duke@435 556 }
duke@435 557
duke@435 558 if (!is_duplicate) { // we don't want duplicate miranda entries in the vtable
duke@435 559 if (is_miranda(im, class_methods, super)) { // is it a miranda at all?
duke@435 560 instanceKlass *sk = instanceKlass::cast(super);
duke@435 561 // check if it is a duplicate of a super's miranda
duke@435 562 if (sk->lookup_method_in_all_interfaces(im->name(), im->signature()) == NULL) {
duke@435 563 list_of_current_mirandas->append(im);
duke@435 564 }
duke@435 565 }
duke@435 566 }
duke@435 567 }
duke@435 568 }
duke@435 569
duke@435 570 void klassVtable::get_mirandas(GrowableArray<methodOop>* mirandas,
duke@435 571 klassOop super, objArrayOop class_methods,
duke@435 572 objArrayOop local_interfaces) {
duke@435 573 assert((mirandas->length() == 0) , "current mirandas must be 0");
duke@435 574
duke@435 575 // iterate thru the local interfaces looking for a miranda
duke@435 576 int num_local_ifs = local_interfaces->length();
duke@435 577 for (int i = 0; i < num_local_ifs; i++) {
duke@435 578 instanceKlass *ik = instanceKlass::cast(klassOop(local_interfaces->obj_at(i)));
duke@435 579 add_new_mirandas_to_list(mirandas, ik->methods(), class_methods, super);
duke@435 580 // iterate thru each local's super interfaces
duke@435 581 objArrayOop super_ifs = ik->transitive_interfaces();
duke@435 582 int num_super_ifs = super_ifs->length();
duke@435 583 for (int j = 0; j < num_super_ifs; j++) {
duke@435 584 instanceKlass *sik = instanceKlass::cast(klassOop(super_ifs->obj_at(j)));
duke@435 585 add_new_mirandas_to_list(mirandas, sik->methods(), class_methods, super);
duke@435 586 }
duke@435 587 }
duke@435 588 }
duke@435 589
duke@435 590 // get number of mirandas
duke@435 591 int klassVtable::get_num_mirandas(klassOop super, objArrayOop class_methods, objArrayOop local_interfaces) {
duke@435 592 ResourceMark rm;
duke@435 593 GrowableArray<methodOop>* mirandas = new GrowableArray<methodOop>(20);
duke@435 594 get_mirandas(mirandas, super, class_methods, local_interfaces);
duke@435 595 return mirandas->length();
duke@435 596 }
duke@435 597
duke@435 598 // fill in mirandas
duke@435 599 void klassVtable::fill_in_mirandas(int& initialized) {
duke@435 600 ResourceMark rm;
duke@435 601 GrowableArray<methodOop>* mirandas = new GrowableArray<methodOop>(20);
duke@435 602 instanceKlass *this_ik = ik();
duke@435 603 get_mirandas(mirandas, this_ik->super(), this_ik->methods(), this_ik->local_interfaces());
duke@435 604 int num_mirandas = mirandas->length();
duke@435 605 for (int i = 0; i < num_mirandas; i++) {
duke@435 606 put_method_at(mirandas->at(i), initialized);
duke@435 607 initialized++;
duke@435 608 }
duke@435 609 }
duke@435 610
duke@435 611 void klassVtable::copy_vtable_to(vtableEntry* start) {
duke@435 612 Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size());
duke@435 613 }
duke@435 614
duke@435 615 void klassVtable::adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
duke@435 616 int methods_length, bool * trace_name_printed) {
duke@435 617 // search the vtable for uses of either obsolete or EMCP methods
duke@435 618 for (int j = 0; j < methods_length; j++) {
duke@435 619 methodOop old_method = old_methods[j];
duke@435 620 methodOop new_method = new_methods[j];
duke@435 621
duke@435 622 // In the vast majority of cases we could get the vtable index
duke@435 623 // by using: old_method->vtable_index()
duke@435 624 // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX()
duke@435 625 // in sun.awt.X11.XFramePeer where methods occur more than once in the
duke@435 626 // vtable, so, alas, we must do an exhaustive search.
duke@435 627 for (int index = 0; index < length(); index++) {
duke@435 628 if (unchecked_method_at(index) == old_method) {
duke@435 629 put_method_at(new_method, index);
duke@435 630
duke@435 631 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
duke@435 632 if (!(*trace_name_printed)) {
duke@435 633 // RC_TRACE_MESG macro has an embedded ResourceMark
duke@435 634 RC_TRACE_MESG(("adjust: name=%s",
duke@435 635 Klass::cast(old_method->method_holder())->external_name()));
duke@435 636 *trace_name_printed = true;
duke@435 637 }
duke@435 638 // RC_TRACE macro has an embedded ResourceMark
duke@435 639 RC_TRACE(0x00100000, ("vtable method update: %s(%s)",
duke@435 640 new_method->name()->as_C_string(),
duke@435 641 new_method->signature()->as_C_string()));
duke@435 642 }
duke@435 643 }
duke@435 644 }
duke@435 645 }
duke@435 646 }
duke@435 647
duke@435 648
duke@435 649 // Garbage collection
duke@435 650 void klassVtable::oop_follow_contents() {
duke@435 651 int len = length();
duke@435 652 for (int i = 0; i < len; i++) {
duke@435 653 MarkSweep::mark_and_push(adr_method_at(i));
duke@435 654 }
duke@435 655 }
duke@435 656
duke@435 657 #ifndef SERIALGC
duke@435 658 void klassVtable::oop_follow_contents(ParCompactionManager* cm) {
duke@435 659 int len = length();
duke@435 660 for (int i = 0; i < len; i++) {
duke@435 661 PSParallelCompact::mark_and_push(cm, adr_method_at(i));
duke@435 662 }
duke@435 663 }
duke@435 664 #endif // SERIALGC
duke@435 665
duke@435 666 void klassVtable::oop_adjust_pointers() {
duke@435 667 int len = length();
duke@435 668 for (int i = 0; i < len; i++) {
duke@435 669 MarkSweep::adjust_pointer(adr_method_at(i));
duke@435 670 }
duke@435 671 }
duke@435 672
duke@435 673 #ifndef SERIALGC
duke@435 674 void klassVtable::oop_update_pointers(ParCompactionManager* cm) {
duke@435 675 const int n = length();
duke@435 676 for (int i = 0; i < n; i++) {
duke@435 677 PSParallelCompact::adjust_pointer(adr_method_at(i));
duke@435 678 }
duke@435 679 }
duke@435 680 #endif // SERIALGC
duke@435 681
duke@435 682 // Iterators
duke@435 683 void klassVtable::oop_oop_iterate(OopClosure* blk) {
duke@435 684 int len = length();
duke@435 685 for (int i = 0; i < len; i++) {
duke@435 686 blk->do_oop(adr_method_at(i));
duke@435 687 }
duke@435 688 }
duke@435 689
duke@435 690 void klassVtable::oop_oop_iterate_m(OopClosure* blk, MemRegion mr) {
duke@435 691 int len = length();
duke@435 692 int i;
duke@435 693 for (i = 0; i < len; i++) {
duke@435 694 if ((HeapWord*)adr_method_at(i) >= mr.start()) break;
duke@435 695 }
duke@435 696 for (; i < len; i++) {
duke@435 697 oop* adr = adr_method_at(i);
duke@435 698 if ((HeapWord*)adr < mr.end()) blk->do_oop(adr);
duke@435 699 }
duke@435 700 }
duke@435 701
duke@435 702 //-----------------------------------------------------------------------------------------
duke@435 703 // Itable code
duke@435 704
duke@435 705 // Initialize a itableMethodEntry
duke@435 706 void itableMethodEntry::initialize(methodOop m) {
duke@435 707 if (m == NULL) return;
duke@435 708
duke@435 709 _method = m;
duke@435 710 }
duke@435 711
duke@435 712 klassItable::klassItable(instanceKlassHandle klass) {
duke@435 713 _klass = klass;
duke@435 714
duke@435 715 if (klass->itable_length() > 0) {
duke@435 716 itableOffsetEntry* offset_entry = (itableOffsetEntry*)klass->start_of_itable();
duke@435 717 if (offset_entry != NULL && offset_entry->interface_klass() != NULL) { // Check that itable is initialized
duke@435 718 // First offset entry points to the first method_entry
duke@435 719 intptr_t* method_entry = (intptr_t *)(((address)klass->as_klassOop()) + offset_entry->offset());
duke@435 720 intptr_t* end = klass->end_of_itable();
duke@435 721
duke@435 722 _table_offset = (intptr_t*)offset_entry - (intptr_t*)klass->as_klassOop();
duke@435 723 _size_offset_table = (method_entry - ((intptr_t*)offset_entry)) / itableOffsetEntry::size();
duke@435 724 _size_method_table = (end - method_entry) / itableMethodEntry::size();
duke@435 725 assert(_table_offset >= 0 && _size_offset_table >= 0 && _size_method_table >= 0, "wrong computation");
duke@435 726 return;
duke@435 727 }
duke@435 728 }
duke@435 729
dcubed@451 730 // The length of the itable was either zero, or it has not yet been initialized.
duke@435 731 _table_offset = 0;
duke@435 732 _size_offset_table = 0;
duke@435 733 _size_method_table = 0;
duke@435 734 }
duke@435 735
duke@435 736 // Garbage Collection
duke@435 737
duke@435 738 void klassItable::oop_follow_contents() {
duke@435 739 // offset table
duke@435 740 itableOffsetEntry* ioe = offset_entry(0);
duke@435 741 for(int i = 0; i < _size_offset_table; i++) {
duke@435 742 MarkSweep::mark_and_push((oop*)&ioe->_interface);
duke@435 743 ioe++;
duke@435 744 }
duke@435 745
duke@435 746 // method table
duke@435 747 itableMethodEntry* ime = method_entry(0);
duke@435 748 for(int j = 0; j < _size_method_table; j++) {
duke@435 749 MarkSweep::mark_and_push((oop*)&ime->_method);
duke@435 750 ime++;
duke@435 751 }
duke@435 752 }
duke@435 753
duke@435 754 #ifndef SERIALGC
duke@435 755 void klassItable::oop_follow_contents(ParCompactionManager* cm) {
duke@435 756 // offset table
duke@435 757 itableOffsetEntry* ioe = offset_entry(0);
duke@435 758 for(int i = 0; i < _size_offset_table; i++) {
duke@435 759 PSParallelCompact::mark_and_push(cm, (oop*)&ioe->_interface);
duke@435 760 ioe++;
duke@435 761 }
duke@435 762
duke@435 763 // method table
duke@435 764 itableMethodEntry* ime = method_entry(0);
duke@435 765 for(int j = 0; j < _size_method_table; j++) {
duke@435 766 PSParallelCompact::mark_and_push(cm, (oop*)&ime->_method);
duke@435 767 ime++;
duke@435 768 }
duke@435 769 }
duke@435 770 #endif // SERIALGC
duke@435 771
duke@435 772 void klassItable::oop_adjust_pointers() {
duke@435 773 // offset table
duke@435 774 itableOffsetEntry* ioe = offset_entry(0);
duke@435 775 for(int i = 0; i < _size_offset_table; i++) {
duke@435 776 MarkSweep::adjust_pointer((oop*)&ioe->_interface);
duke@435 777 ioe++;
duke@435 778 }
duke@435 779
duke@435 780 // method table
duke@435 781 itableMethodEntry* ime = method_entry(0);
duke@435 782 for(int j = 0; j < _size_method_table; j++) {
duke@435 783 MarkSweep::adjust_pointer((oop*)&ime->_method);
duke@435 784 ime++;
duke@435 785 }
duke@435 786 }
duke@435 787
duke@435 788 #ifndef SERIALGC
duke@435 789 void klassItable::oop_update_pointers(ParCompactionManager* cm) {
duke@435 790 // offset table
duke@435 791 itableOffsetEntry* ioe = offset_entry(0);
duke@435 792 for(int i = 0; i < _size_offset_table; i++) {
duke@435 793 PSParallelCompact::adjust_pointer((oop*)&ioe->_interface);
duke@435 794 ioe++;
duke@435 795 }
duke@435 796
duke@435 797 // method table
duke@435 798 itableMethodEntry* ime = method_entry(0);
duke@435 799 for(int j = 0; j < _size_method_table; j++) {
duke@435 800 PSParallelCompact::adjust_pointer((oop*)&ime->_method);
duke@435 801 ime++;
duke@435 802 }
duke@435 803 }
duke@435 804 #endif // SERIALGC
duke@435 805
duke@435 806 // Iterators
duke@435 807 void klassItable::oop_oop_iterate(OopClosure* blk) {
duke@435 808 // offset table
duke@435 809 itableOffsetEntry* ioe = offset_entry(0);
duke@435 810 for(int i = 0; i < _size_offset_table; i++) {
duke@435 811 blk->do_oop((oop*)&ioe->_interface);
duke@435 812 ioe++;
duke@435 813 }
duke@435 814
duke@435 815 // method table
duke@435 816 itableMethodEntry* ime = method_entry(0);
duke@435 817 for(int j = 0; j < _size_method_table; j++) {
duke@435 818 blk->do_oop((oop*)&ime->_method);
duke@435 819 ime++;
duke@435 820 }
duke@435 821 }
duke@435 822
duke@435 823 void klassItable::oop_oop_iterate_m(OopClosure* blk, MemRegion mr) {
duke@435 824 // offset table
duke@435 825 itableOffsetEntry* ioe = offset_entry(0);
duke@435 826 for(int i = 0; i < _size_offset_table; i++) {
duke@435 827 oop* adr = (oop*)&ioe->_interface;
duke@435 828 if (mr.contains(adr)) blk->do_oop(adr);
duke@435 829 ioe++;
duke@435 830 }
duke@435 831
duke@435 832 // method table
duke@435 833 itableMethodEntry* ime = method_entry(0);
duke@435 834 for(int j = 0; j < _size_method_table; j++) {
duke@435 835 oop* adr = (oop*)&ime->_method;
duke@435 836 if (mr.contains(adr)) blk->do_oop(adr);
duke@435 837 ime++;
duke@435 838 }
duke@435 839 }
duke@435 840
duke@435 841
duke@435 842 static int initialize_count = 0;
duke@435 843
duke@435 844 // Initialization
duke@435 845 void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
dcubed@451 846 // Cannot be setup doing bootstrapping, interfaces don't have
dcubed@451 847 // itables, and klass with only ones entry have empty itables
dcubed@451 848 if (Universe::is_bootstrapping() ||
dcubed@451 849 _klass->is_interface() ||
dcubed@451 850 _klass->itable_length() == itableOffsetEntry::size()) return;
duke@435 851
dcubed@451 852 // There's alway an extra itable entry so we can null-terminate it.
dcubed@451 853 guarantee(size_offset_table() >= 1, "too small");
dcubed@451 854 int num_interfaces = size_offset_table() - 1;
duke@435 855 if (num_interfaces > 0) {
dcubed@451 856 if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count,
dcubed@451 857 _klass->name()->as_C_string());
duke@435 858
duke@435 859
acorn@1087 860 // Iterate through all interfaces
duke@435 861 int i;
duke@435 862 for(i = 0; i < num_interfaces; i++) {
duke@435 863 itableOffsetEntry* ioe = offset_entry(i);
duke@435 864 KlassHandle interf_h (THREAD, ioe->interface_klass());
duke@435 865 assert(interf_h() != NULL && ioe->offset() != 0, "bad offset entry in itable");
duke@435 866 initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK);
duke@435 867 }
duke@435 868
duke@435 869 }
dcubed@451 870 // Check that the last entry is empty
dcubed@451 871 itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1);
dcubed@451 872 guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing");
duke@435 873 }
duke@435 874
duke@435 875
duke@435 876 void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) {
duke@435 877 objArrayHandle methods(THREAD, instanceKlass::cast(interf_h())->methods());
duke@435 878 int nof_methods = methods()->length();
duke@435 879 HandleMark hm;
duke@435 880 KlassHandle klass = _klass;
jcoomes@1844 881 assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
duke@435 882 Handle interface_loader (THREAD, instanceKlass::cast(interf_h())->class_loader());
duke@435 883 int ime_num = 0;
duke@435 884
duke@435 885 // Skip first methodOop if it is a class initializer
kamg@2616 886 int i = ((methodOop)methods()->obj_at(0))->is_static_initializer() ? 1 : 0;
duke@435 887
duke@435 888 // m, method_name, method_signature, klass reset each loop so they
duke@435 889 // don't need preserving across check_signature_loaders call
duke@435 890 // methods needs a handle in case of gc from check_signature_loaders
duke@435 891 for(; i < nof_methods; i++) {
duke@435 892 methodOop m = (methodOop)methods()->obj_at(i);
coleenp@2497 893 Symbol* method_name = m->name();
coleenp@2497 894 Symbol* method_signature = m->signature();
duke@435 895
duke@435 896 // This is same code as in Linkresolver::lookup_instance_method_in_klasses
duke@435 897 methodOop target = klass->uncached_lookup_method(method_name, method_signature);
duke@435 898 while (target != NULL && target->is_static()) {
duke@435 899 // continue with recursive lookup through the superclass
duke@435 900 klassOop super = Klass::cast(target->method_holder())->super();
duke@435 901 target = (super == NULL) ? methodOop(NULL) : Klass::cast(super)->uncached_lookup_method(method_name, method_signature);
duke@435 902 }
duke@435 903 if (target == NULL || !target->is_public() || target->is_abstract()) {
duke@435 904 // Entry do not resolve. Leave it empty
duke@435 905 } else {
duke@435 906 // Entry did resolve, check loader constraints before initializing
duke@435 907 // if checkconstraints requested
duke@435 908 methodHandle target_h (THREAD, target); // preserve across gc
duke@435 909 if (checkconstraints) {
duke@435 910 Handle method_holder_loader (THREAD, instanceKlass::cast(target->method_holder())->class_loader());
duke@435 911 if (method_holder_loader() != interface_loader()) {
duke@435 912 ResourceMark rm(THREAD);
duke@435 913 char* failed_type_name =
duke@435 914 SystemDictionary::check_signature_loaders(method_signature,
duke@435 915 method_holder_loader,
duke@435 916 interface_loader,
duke@435 917 true, CHECK);
duke@435 918 if (failed_type_name != NULL) {
duke@435 919 const char* msg = "loader constraint violation in interface "
duke@435 920 "itable initialization: when resolving method \"%s\" the class"
duke@435 921 " loader (instance of %s) of the current class, %s, "
duke@435 922 "and the class loader (instance of %s) for interface "
duke@435 923 "%s have different Class objects for the type %s "
duke@435 924 "used in the signature";
duke@435 925 char* sig = target_h()->name_and_sig_as_C_string();
duke@435 926 const char* loader1 = SystemDictionary::loader_name(method_holder_loader());
duke@435 927 char* current = klass->name()->as_C_string();
duke@435 928 const char* loader2 = SystemDictionary::loader_name(interface_loader());
duke@435 929 char* iface = instanceKlass::cast(interf_h())->name()->as_C_string();
duke@435 930 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
duke@435 931 strlen(current) + strlen(loader2) + strlen(iface) +
duke@435 932 strlen(failed_type_name);
duke@435 933 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
duke@435 934 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
duke@435 935 iface, failed_type_name);
duke@435 936 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
duke@435 937 }
duke@435 938 }
duke@435 939 }
duke@435 940
duke@435 941 // ime may have moved during GC so recalculate address
duke@435 942 itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target_h());
duke@435 943 }
duke@435 944 // Progress to next entry
duke@435 945 ime_num++;
duke@435 946 }
duke@435 947 }
duke@435 948
dcubed@451 949 // Update entry for specific methodOop
duke@435 950 void klassItable::initialize_with_method(methodOop m) {
duke@435 951 itableMethodEntry* ime = method_entry(0);
duke@435 952 for(int i = 0; i < _size_method_table; i++) {
duke@435 953 if (ime->method() == m) {
duke@435 954 ime->initialize(m);
duke@435 955 }
duke@435 956 ime++;
duke@435 957 }
duke@435 958 }
duke@435 959
duke@435 960 void klassItable::adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
duke@435 961 int methods_length, bool * trace_name_printed) {
duke@435 962 // search the itable for uses of either obsolete or EMCP methods
duke@435 963 for (int j = 0; j < methods_length; j++) {
duke@435 964 methodOop old_method = old_methods[j];
duke@435 965 methodOop new_method = new_methods[j];
duke@435 966 itableMethodEntry* ime = method_entry(0);
duke@435 967
dcubed@1045 968 // The itable can describe more than one interface and the same
dcubed@1045 969 // method signature can be specified by more than one interface.
dcubed@1045 970 // This means we have to do an exhaustive search to find all the
dcubed@1045 971 // old_method references.
duke@435 972 for (int i = 0; i < _size_method_table; i++) {
duke@435 973 if (ime->method() == old_method) {
duke@435 974 ime->initialize(new_method);
duke@435 975
duke@435 976 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
duke@435 977 if (!(*trace_name_printed)) {
duke@435 978 // RC_TRACE_MESG macro has an embedded ResourceMark
duke@435 979 RC_TRACE_MESG(("adjust: name=%s",
duke@435 980 Klass::cast(old_method->method_holder())->external_name()));
duke@435 981 *trace_name_printed = true;
duke@435 982 }
duke@435 983 // RC_TRACE macro has an embedded ResourceMark
duke@435 984 RC_TRACE(0x00200000, ("itable method update: %s(%s)",
duke@435 985 new_method->name()->as_C_string(),
duke@435 986 new_method->signature()->as_C_string()));
duke@435 987 }
acorn@1087 988 break;
duke@435 989 }
duke@435 990 ime++;
duke@435 991 }
duke@435 992 }
duke@435 993 }
duke@435 994
duke@435 995
duke@435 996 // Setup
duke@435 997 class InterfaceVisiterClosure : public StackObj {
duke@435 998 public:
duke@435 999 virtual void doit(klassOop intf, int method_count) = 0;
duke@435 1000 };
duke@435 1001
duke@435 1002 // Visit all interfaces with at-least one method (excluding <clinit>)
duke@435 1003 void visit_all_interfaces(objArrayOop transitive_intf, InterfaceVisiterClosure *blk) {
duke@435 1004 // Handle array argument
duke@435 1005 for(int i = 0; i < transitive_intf->length(); i++) {
duke@435 1006 klassOop intf = (klassOop)transitive_intf->obj_at(i);
duke@435 1007 assert(Klass::cast(intf)->is_interface(), "sanity check");
duke@435 1008
duke@435 1009 // Find no. of methods excluding a <clinit>
duke@435 1010 int method_count = instanceKlass::cast(intf)->methods()->length();
duke@435 1011 if (method_count > 0) {
duke@435 1012 methodOop m = (methodOop)instanceKlass::cast(intf)->methods()->obj_at(0);
duke@435 1013 assert(m != NULL && m->is_method(), "sanity check");
duke@435 1014 if (m->name() == vmSymbols::object_initializer_name()) {
duke@435 1015 method_count--;
duke@435 1016 }
duke@435 1017 }
duke@435 1018
duke@435 1019 // Only count interfaces with at least one method
duke@435 1020 if (method_count > 0) {
duke@435 1021 blk->doit(intf, method_count);
duke@435 1022 }
duke@435 1023 }
duke@435 1024 }
duke@435 1025
duke@435 1026 class CountInterfacesClosure : public InterfaceVisiterClosure {
duke@435 1027 private:
duke@435 1028 int _nof_methods;
duke@435 1029 int _nof_interfaces;
duke@435 1030 public:
duke@435 1031 CountInterfacesClosure() { _nof_methods = 0; _nof_interfaces = 0; }
duke@435 1032
duke@435 1033 int nof_methods() const { return _nof_methods; }
duke@435 1034 int nof_interfaces() const { return _nof_interfaces; }
duke@435 1035
duke@435 1036 void doit(klassOop intf, int method_count) { _nof_methods += method_count; _nof_interfaces++; }
duke@435 1037 };
duke@435 1038
duke@435 1039 class SetupItableClosure : public InterfaceVisiterClosure {
duke@435 1040 private:
duke@435 1041 itableOffsetEntry* _offset_entry;
duke@435 1042 itableMethodEntry* _method_entry;
duke@435 1043 address _klass_begin;
duke@435 1044 public:
duke@435 1045 SetupItableClosure(address klass_begin, itableOffsetEntry* offset_entry, itableMethodEntry* method_entry) {
duke@435 1046 _klass_begin = klass_begin;
duke@435 1047 _offset_entry = offset_entry;
duke@435 1048 _method_entry = method_entry;
duke@435 1049 }
duke@435 1050
duke@435 1051 itableMethodEntry* method_entry() const { return _method_entry; }
duke@435 1052
duke@435 1053 void doit(klassOop intf, int method_count) {
duke@435 1054 int offset = ((address)_method_entry) - _klass_begin;
duke@435 1055 _offset_entry->initialize(intf, offset);
duke@435 1056 _offset_entry++;
duke@435 1057 _method_entry += method_count;
duke@435 1058 }
duke@435 1059 };
duke@435 1060
duke@435 1061 int klassItable::compute_itable_size(objArrayHandle transitive_interfaces) {
duke@435 1062 // Count no of interfaces and total number of interface methods
duke@435 1063 CountInterfacesClosure cic;
duke@435 1064 visit_all_interfaces(transitive_interfaces(), &cic);
duke@435 1065
dcubed@451 1066 // There's alway an extra itable entry so we can null-terminate it.
dcubed@451 1067 int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods());
duke@435 1068
duke@435 1069 // Statistics
duke@435 1070 update_stats(itable_size * HeapWordSize);
duke@435 1071
duke@435 1072 return itable_size;
duke@435 1073 }
duke@435 1074
duke@435 1075
duke@435 1076 // Fill out offset table and interface klasses into the itable space
duke@435 1077 void klassItable::setup_itable_offset_table(instanceKlassHandle klass) {
duke@435 1078 if (klass->itable_length() == 0) return;
duke@435 1079 assert(!klass->is_interface(), "Should have zero length itable");
duke@435 1080
duke@435 1081 // Count no of interfaces and total number of interface methods
duke@435 1082 CountInterfacesClosure cic;
duke@435 1083 visit_all_interfaces(klass->transitive_interfaces(), &cic);
duke@435 1084 int nof_methods = cic.nof_methods();
duke@435 1085 int nof_interfaces = cic.nof_interfaces();
duke@435 1086
dcubed@451 1087 // Add one extra entry so we can null-terminate the table
dcubed@451 1088 nof_interfaces++;
duke@435 1089
duke@435 1090 assert(compute_itable_size(objArrayHandle(klass->transitive_interfaces())) ==
duke@435 1091 calc_itable_size(nof_interfaces, nof_methods),
duke@435 1092 "mismatch calculation of itable size");
duke@435 1093
duke@435 1094 // Fill-out offset table
duke@435 1095 itableOffsetEntry* ioe = (itableOffsetEntry*)klass->start_of_itable();
duke@435 1096 itableMethodEntry* ime = (itableMethodEntry*)(ioe + nof_interfaces);
duke@435 1097 intptr_t* end = klass->end_of_itable();
never@2658 1098 assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_nonstatic_oop_maps(), "wrong offset calculation (1)");
coleenp@548 1099 assert((oop*)(end) == (oop*)(ime + nof_methods), "wrong offset calculation (2)");
duke@435 1100
duke@435 1101 // Visit all interfaces and initialize itable offset table
duke@435 1102 SetupItableClosure sic((address)klass->as_klassOop(), ioe, ime);
duke@435 1103 visit_all_interfaces(klass->transitive_interfaces(), &sic);
duke@435 1104
duke@435 1105 #ifdef ASSERT
duke@435 1106 ime = sic.method_entry();
duke@435 1107 oop* v = (oop*) klass->end_of_itable();
duke@435 1108 assert( (oop*)(ime) == v, "wrong offset calculation (2)");
duke@435 1109 #endif
duke@435 1110 }
duke@435 1111
duke@435 1112
duke@435 1113 // m must be a method in an interface
duke@435 1114 int klassItable::compute_itable_index(methodOop m) {
duke@435 1115 klassOop intf = m->method_holder();
duke@435 1116 assert(instanceKlass::cast(intf)->is_interface(), "sanity check");
duke@435 1117 objArrayOop methods = instanceKlass::cast(intf)->methods();
duke@435 1118 int index = 0;
duke@435 1119 while(methods->obj_at(index) != m) {
duke@435 1120 index++;
duke@435 1121 assert(index < methods->length(), "should find index for resolve_invoke");
duke@435 1122 }
duke@435 1123 // Adjust for <clinit>, which is left out of table if first method
kamg@2616 1124 if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->is_static_initializer()) {
duke@435 1125 index--;
duke@435 1126 }
duke@435 1127 return index;
duke@435 1128 }
duke@435 1129
jrose@1100 1130
jrose@1100 1131 // inverse to compute_itable_index
jrose@1100 1132 methodOop klassItable::method_for_itable_index(klassOop intf, int itable_index) {
jrose@1100 1133 assert(instanceKlass::cast(intf)->is_interface(), "sanity check");
jrose@1100 1134 objArrayOop methods = instanceKlass::cast(intf)->methods();
jrose@1100 1135
jrose@1100 1136 int index = itable_index;
jrose@1100 1137 // Adjust for <clinit>, which is left out of table if first method
kamg@2616 1138 if (methods->length() > 0 && ((methodOop)methods->obj_at(0))->is_static_initializer()) {
jrose@1100 1139 index++;
jrose@1100 1140 }
jrose@1100 1141
jrose@1100 1142 if (itable_index < 0 || index >= methods->length())
jrose@1100 1143 return NULL; // help caller defend against bad indexes
jrose@1100 1144
jrose@1100 1145 methodOop m = (methodOop)methods->obj_at(index);
jrose@1100 1146 assert(compute_itable_index(m) == itable_index, "correct inverse");
jrose@1100 1147
jrose@1100 1148 return m;
jrose@1100 1149 }
jrose@1100 1150
duke@435 1151 void klassVtable::verify(outputStream* st, bool forced) {
duke@435 1152 // make sure table is initialized
duke@435 1153 if (!Universe::is_fully_initialized()) return;
duke@435 1154 #ifndef PRODUCT
duke@435 1155 // avoid redundant verifies
duke@435 1156 if (!forced && _verify_count == Universe::verify_count()) return;
duke@435 1157 _verify_count = Universe::verify_count();
duke@435 1158 #endif
duke@435 1159 oop* end_of_obj = (oop*)_klass() + _klass()->size();
duke@435 1160 oop* end_of_vtable = (oop *)&table()[_length];
duke@435 1161 if (end_of_vtable > end_of_obj) {
jcoomes@1845 1162 fatal(err_msg("klass %s: klass object too short (vtable extends beyond "
jcoomes@1845 1163 "end)", _klass->internal_name()));
duke@435 1164 }
duke@435 1165
duke@435 1166 for (int i = 0; i < _length; i++) table()[i].verify(this, st);
duke@435 1167 // verify consistency with superKlass vtable
duke@435 1168 klassOop super = _klass->super();
duke@435 1169 if (super != NULL) {
duke@435 1170 instanceKlass* sk = instanceKlass::cast(super);
duke@435 1171 klassVtable* vt = sk->vtable();
duke@435 1172 for (int i = 0; i < vt->length(); i++) {
duke@435 1173 verify_against(st, vt, i);
duke@435 1174 }
duke@435 1175 }
duke@435 1176 }
duke@435 1177
duke@435 1178 void klassVtable::verify_against(outputStream* st, klassVtable* vt, int index) {
duke@435 1179 vtableEntry* vte = &vt->table()[index];
duke@435 1180 if (vte->method()->name() != table()[index].method()->name() ||
duke@435 1181 vte->method()->signature() != table()[index].method()->signature()) {
duke@435 1182 fatal("mismatched name/signature of vtable entries");
duke@435 1183 }
duke@435 1184 }
duke@435 1185
duke@435 1186 #ifndef PRODUCT
duke@435 1187 void klassVtable::print() {
duke@435 1188 ResourceMark rm;
duke@435 1189 tty->print("klassVtable for klass %s (length %d):\n", _klass->internal_name(), length());
duke@435 1190 for (int i = 0; i < length(); i++) {
duke@435 1191 table()[i].print();
duke@435 1192 tty->cr();
duke@435 1193 }
duke@435 1194 }
duke@435 1195 #endif
duke@435 1196
duke@435 1197 void vtableEntry::verify(klassVtable* vt, outputStream* st) {
duke@435 1198 NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true));
duke@435 1199 assert(method() != NULL, "must have set method");
duke@435 1200 method()->verify();
duke@435 1201 // we sub_type, because it could be a miranda method
duke@435 1202 if (!vt->klass()->is_subtype_of(method()->method_holder())) {
duke@435 1203 #ifndef PRODUCT
duke@435 1204 print();
duke@435 1205 #endif
jcoomes@1845 1206 fatal(err_msg("vtableEntry " PTR_FORMAT ": method is from subclass", this));
duke@435 1207 }
duke@435 1208 }
duke@435 1209
duke@435 1210 #ifndef PRODUCT
duke@435 1211
duke@435 1212 void vtableEntry::print() {
duke@435 1213 ResourceMark rm;
duke@435 1214 tty->print("vtableEntry %s: ", method()->name()->as_C_string());
duke@435 1215 if (Verbose) {
duke@435 1216 tty->print("m %#lx ", (address)method());
duke@435 1217 }
duke@435 1218 }
duke@435 1219
duke@435 1220 class VtableStats : AllStatic {
duke@435 1221 public:
duke@435 1222 static int no_klasses; // # classes with vtables
duke@435 1223 static int no_array_klasses; // # array classes
duke@435 1224 static int no_instance_klasses; // # instanceKlasses
duke@435 1225 static int sum_of_vtable_len; // total # of vtable entries
duke@435 1226 static int sum_of_array_vtable_len; // total # of vtable entries in array klasses only
duke@435 1227 static int fixed; // total fixed overhead in bytes
duke@435 1228 static int filler; // overhead caused by filler bytes
duke@435 1229 static int entries; // total bytes consumed by vtable entries
duke@435 1230 static int array_entries; // total bytes consumed by array vtable entries
duke@435 1231
duke@435 1232 static void do_class(klassOop k) {
duke@435 1233 Klass* kl = k->klass_part();
duke@435 1234 klassVtable* vt = kl->vtable();
duke@435 1235 if (vt == NULL) return;
duke@435 1236 no_klasses++;
duke@435 1237 if (kl->oop_is_instance()) {
duke@435 1238 no_instance_klasses++;
duke@435 1239 kl->array_klasses_do(do_class);
duke@435 1240 }
duke@435 1241 if (kl->oop_is_array()) {
duke@435 1242 no_array_klasses++;
duke@435 1243 sum_of_array_vtable_len += vt->length();
duke@435 1244 }
duke@435 1245 sum_of_vtable_len += vt->length();
duke@435 1246 }
duke@435 1247
duke@435 1248 static void compute() {
duke@435 1249 SystemDictionary::classes_do(do_class);
duke@435 1250 fixed = no_klasses * oopSize; // vtable length
duke@435 1251 // filler size is a conservative approximation
duke@435 1252 filler = oopSize * (no_klasses - no_instance_klasses) * (sizeof(instanceKlass) - sizeof(arrayKlass) - 1);
duke@435 1253 entries = sizeof(vtableEntry) * sum_of_vtable_len;
duke@435 1254 array_entries = sizeof(vtableEntry) * sum_of_array_vtable_len;
duke@435 1255 }
duke@435 1256 };
duke@435 1257
duke@435 1258 int VtableStats::no_klasses = 0;
duke@435 1259 int VtableStats::no_array_klasses = 0;
duke@435 1260 int VtableStats::no_instance_klasses = 0;
duke@435 1261 int VtableStats::sum_of_vtable_len = 0;
duke@435 1262 int VtableStats::sum_of_array_vtable_len = 0;
duke@435 1263 int VtableStats::fixed = 0;
duke@435 1264 int VtableStats::filler = 0;
duke@435 1265 int VtableStats::entries = 0;
duke@435 1266 int VtableStats::array_entries = 0;
duke@435 1267
duke@435 1268 void klassVtable::print_statistics() {
duke@435 1269 ResourceMark rm;
duke@435 1270 HandleMark hm;
duke@435 1271 VtableStats::compute();
duke@435 1272 tty->print_cr("vtable statistics:");
duke@435 1273 tty->print_cr("%6d classes (%d instance, %d array)", VtableStats::no_klasses, VtableStats::no_instance_klasses, VtableStats::no_array_klasses);
duke@435 1274 int total = VtableStats::fixed + VtableStats::filler + VtableStats::entries;
duke@435 1275 tty->print_cr("%6d bytes fixed overhead (refs + vtable object header)", VtableStats::fixed);
duke@435 1276 tty->print_cr("%6d bytes filler overhead", VtableStats::filler);
duke@435 1277 tty->print_cr("%6d bytes for vtable entries (%d for arrays)", VtableStats::entries, VtableStats::array_entries);
duke@435 1278 tty->print_cr("%6d bytes total", total);
duke@435 1279 }
duke@435 1280
duke@435 1281 bool klassVtable::check_no_old_entries() {
duke@435 1282 // Check that there really is no entry
duke@435 1283 for (int i = 0; i < length(); i++) {
duke@435 1284 methodOop m = unchecked_method_at(i);
duke@435 1285 if (m != NULL) {
duke@435 1286 if (m->is_old()) {
duke@435 1287 return false;
duke@435 1288 }
duke@435 1289 }
duke@435 1290 }
duke@435 1291 return true;
duke@435 1292 }
duke@435 1293
duke@435 1294 void klassVtable::dump_vtable() {
duke@435 1295 tty->print_cr("vtable dump --");
duke@435 1296 for (int i = 0; i < length(); i++) {
duke@435 1297 methodOop m = unchecked_method_at(i);
duke@435 1298 if (m != NULL) {
duke@435 1299 tty->print(" (%5d) ", i);
duke@435 1300 m->access_flags().print_on(tty);
duke@435 1301 tty->print(" -- ");
duke@435 1302 m->print_name(tty);
duke@435 1303 tty->cr();
duke@435 1304 }
duke@435 1305 }
duke@435 1306 }
duke@435 1307
duke@435 1308 int klassItable::_total_classes; // Total no. of classes with itables
duke@435 1309 long klassItable::_total_size; // Total no. of bytes used for itables
duke@435 1310
duke@435 1311 void klassItable::print_statistics() {
duke@435 1312 tty->print_cr("itable statistics:");
duke@435 1313 tty->print_cr("%6d classes with itables", _total_classes);
duke@435 1314 tty->print_cr("%6d K uses for itables (average by class: %d bytes)", _total_size / K, _total_size / _total_classes);
duke@435 1315 }
duke@435 1316
duke@435 1317 #endif // PRODUCT

mercurial