src/share/vm/prims/jvmtiRedefineClasses.cpp

Print this page


   1 /*
   2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 112     // a shared class. We do the remap during the doit() phase of
 113     // the safepoint to be safer.
 114     if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
 115       RC_TRACE_WITH_THREAD(0x00000001, thread,
 116         ("failed to remap shared readonly space to readwrite, private"));
 117       _res = JVMTI_ERROR_INTERNAL;
 118       return;
 119     }
 120   }
 121 
 122   for (int i = 0; i < _class_count; i++) {
 123     redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread);
 124   }
 125   // Disable any dependent concurrent compilations
 126   SystemDictionary::notice_modification();
 127 
 128   // Set flag indicating that some invariants are no longer true.
 129   // See jvmtiExport.hpp for detailed explanation.
 130   JvmtiExport::set_has_redefined_a_class();
 131 
 132 #ifdef ASSERT





 133   SystemDictionary::classes_do(check_class, thread);


 134 #endif
 135 }
 136 
 137 void VM_RedefineClasses::doit_epilogue() {
 138   // Free os::malloc allocated memory.
 139   // The memory allocated in redefine will be free'ed in next VM operation.
 140   os::free(_scratch_classes);
 141 
 142   if (RC_TRACE_ENABLED(0x00000004)) {
 143     // Used to have separate timers for "doit" and "all", but the timer
 144     // overhead skewed the measurements.
 145     jlong doit_time = _timer_rsc_phase1.milliseconds() +
 146                       _timer_rsc_phase2.milliseconds();
 147     jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
 148 
 149     RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
 150       "  prologue=" UINT64_FORMAT "  doit=" UINT64_FORMAT, all_time,
 151       _timer_vm_op_prologue.milliseconds(), doit_time));
 152     RC_TRACE(0x00000004,
 153       ("redefine_single_class: phase1=" UINT64_FORMAT "  phase2=" UINT64_FORMAT,


3351   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
3352   java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
3353 
3354   if (class_oop != _the_class_oop) {
3355     // _the_class_oop count is printed at end of redefine_single_class()
3356     RC_TRACE_WITH_THREAD(0x00000008, THREAD,
3357       ("updated count in subclass=%s to %d", ik->external_name(), new_count));
3358   }
3359 
3360   for (Klass *subk = ik->subklass(); subk != NULL;
3361        subk = subk->next_sibling()) {
3362     if (subk->oop_is_instance()) {
3363       // Only update instanceKlasses
3364       instanceKlass *subik = (instanceKlass*)subk;
3365       // recursively do subclasses of the current subclass
3366       increment_class_counter(subik, THREAD);
3367     }
3368   }
3369 }
3370 
3371 #ifndef PRODUCT
3372 void VM_RedefineClasses::check_class(klassOop k_oop,
3373        oop initiating_loader, TRAPS) {
3374   Klass *k = k_oop->klass_part();
3375   if (k->oop_is_instance()) {
3376     HandleMark hm(THREAD);
3377     instanceKlass *ik = (instanceKlass *) k;
3378 
3379     if (ik->vtable_length() > 0) {
3380       ResourceMark rm(THREAD);
3381       if (!ik->vtable()->check_no_old_entries()) {
3382         tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());







3383         ik->vtable()->dump_vtable();

































3384         dump_methods();
3385         assert(false, "OLD method found");


3386       }

3387     }
3388   }
3389 }
3390 
3391 void VM_RedefineClasses::dump_methods() {
3392         int j;
3393         tty->print_cr("_old_methods --");
3394         for (j = 0; j < _old_methods->length(); ++j) {
3395           methodOop m = (methodOop) _old_methods->obj_at(j);
3396           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3397           m->access_flags().print_on(tty);
3398           tty->print(" --  ");
3399           m->print_name(tty);
3400           tty->cr();
3401         }
3402         tty->print_cr("_new_methods --");
3403         for (j = 0; j < _new_methods->length(); ++j) {
3404           methodOop m = (methodOop) _new_methods->obj_at(j);
3405           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3406           m->access_flags().print_on(tty);
3407           tty->print(" --  ");
3408           m->print_name(tty);
3409           tty->cr();
3410         }
3411         tty->print_cr("_matching_(old/new)_methods --");
3412         for (j = 0; j < _matching_methods_length; ++j) {
3413           methodOop m = _matching_old_methods[j];
3414           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3415           m->access_flags().print_on(tty);
3416           tty->print(" --  ");
3417           m->print_name(tty);
3418           tty->cr();
3419           m = _matching_new_methods[j];
3420           tty->print("      (%5d)  ", m->vtable_index());
3421           m->access_flags().print_on(tty);
3422           tty->cr();
3423         }
3424         tty->print_cr("_deleted_methods --");
3425         for (j = 0; j < _deleted_methods_length; ++j) {
3426           methodOop m = _deleted_methods[j];
3427           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3428           m->access_flags().print_on(tty);
3429           tty->print(" --  ");
3430           m->print_name(tty);
3431           tty->cr();
3432         }
3433         tty->print_cr("_added_methods --");
3434         for (j = 0; j < _added_methods_length; ++j) {
3435           methodOop m = _added_methods[j];
3436           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3437           m->access_flags().print_on(tty);
3438           tty->print(" --  ");
3439           m->print_name(tty);
3440           tty->cr();
3441         }
3442 }
3443 #endif
   1 /*
   2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 112     // a shared class. We do the remap during the doit() phase of
 113     // the safepoint to be safer.
 114     if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
 115       RC_TRACE_WITH_THREAD(0x00000001, thread,
 116         ("failed to remap shared readonly space to readwrite, private"));
 117       _res = JVMTI_ERROR_INTERNAL;
 118       return;
 119     }
 120   }
 121 
 122   for (int i = 0; i < _class_count; i++) {
 123     redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread);
 124   }
 125   // Disable any dependent concurrent compilations
 126   SystemDictionary::notice_modification();
 127 
 128   // Set flag indicating that some invariants are no longer true.
 129   // See jvmtiExport.hpp for detailed explanation.
 130   JvmtiExport::set_has_redefined_a_class();
 131 
 132 // check_class() is optionally called for product bits, but is
 133 // always called for non-product bits.
 134 #ifdef PRODUCT
 135   if (RC_TRACE_ENABLED(0x00004000)) {
 136 #endif
 137     RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
 138     SystemDictionary::classes_do(check_class, thread);
 139 #ifdef PRODUCT
 140   }
 141 #endif
 142 }
 143 
 144 void VM_RedefineClasses::doit_epilogue() {
 145   // Free os::malloc allocated memory.
 146   // The memory allocated in redefine will be free'ed in next VM operation.
 147   os::free(_scratch_classes);
 148 
 149   if (RC_TRACE_ENABLED(0x00000004)) {
 150     // Used to have separate timers for "doit" and "all", but the timer
 151     // overhead skewed the measurements.
 152     jlong doit_time = _timer_rsc_phase1.milliseconds() +
 153                       _timer_rsc_phase2.milliseconds();
 154     jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
 155 
 156     RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
 157       "  prologue=" UINT64_FORMAT "  doit=" UINT64_FORMAT, all_time,
 158       _timer_vm_op_prologue.milliseconds(), doit_time));
 159     RC_TRACE(0x00000004,
 160       ("redefine_single_class: phase1=" UINT64_FORMAT "  phase2=" UINT64_FORMAT,


3358   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
3359   java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
3360 
3361   if (class_oop != _the_class_oop) {
3362     // _the_class_oop count is printed at end of redefine_single_class()
3363     RC_TRACE_WITH_THREAD(0x00000008, THREAD,
3364       ("updated count in subclass=%s to %d", ik->external_name(), new_count));
3365   }
3366 
3367   for (Klass *subk = ik->subklass(); subk != NULL;
3368        subk = subk->next_sibling()) {
3369     if (subk->oop_is_instance()) {
3370       // Only update instanceKlasses
3371       instanceKlass *subik = (instanceKlass*)subk;
3372       // recursively do subclasses of the current subclass
3373       increment_class_counter(subik, THREAD);
3374     }
3375   }
3376 }
3377 

3378 void VM_RedefineClasses::check_class(klassOop k_oop,
3379        oop initiating_loader, TRAPS) {
3380   Klass *k = k_oop->klass_part();
3381   if (k->oop_is_instance()) {
3382     HandleMark hm(THREAD);
3383     instanceKlass *ik = (instanceKlass *) k;
3384     bool no_old_methods = true;  // be optimistic

3385     ResourceMark rm(THREAD);
3386 
3387     // a vtable should never contain old or obsolete methods
3388     if (ik->vtable_length() > 0 &&
3389         !ik->vtable()->check_no_old_or_obsolete_entries()) {
3390       if (RC_TRACE_ENABLED(0x00004000)) {
3391         RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3392           ("klassVtable::check_no_old_or_obsolete_entries failure"
3393            " -- OLD or OBSOLETE method found -- class: %s",
3394            ik->signature_name()));
3395         ik->vtable()->dump_vtable();
3396       }
3397       no_old_methods = false;
3398     }
3399 
3400     // an itable should never contain old or obsolete methods
3401     if (ik->itable_length() > 0 &&
3402         !ik->itable()->check_no_old_or_obsolete_entries()) {
3403       if (RC_TRACE_ENABLED(0x00004000)) {
3404         RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3405           ("klassItable::check_no_old_or_obsolete_entries failure"
3406            " -- OLD or OBSOLETE method found -- class: %s",
3407            ik->signature_name()));
3408         ik->itable()->dump_itable();
3409       }
3410       no_old_methods = false;
3411     }
3412 
3413     // the constant pool cache should never contain old or obsolete methods
3414     if (ik->constants() != NULL &&
3415         ik->constants()->cache() != NULL &&
3416         !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
3417       if (RC_TRACE_ENABLED(0x00004000)) {
3418         RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3419           ("cp-cache::check_no_old_or_obsolete_entries failure"
3420            " -- OLD or OBSOLETE method found -- class: %s",
3421            ik->signature_name()));
3422         ik->constants()->cache()->dump_cache();
3423       }
3424       no_old_methods = false;
3425     }
3426 
3427     if (!no_old_methods) {
3428       if (RC_TRACE_ENABLED(0x00004000)) {
3429         dump_methods();
3430       } else {
3431         tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
3432           "to see more info about the following guarantee() failure.");
3433       }
3434       guarantee(false, "OLD and/or OBSOLETE method(s) found");
3435     }
3436   }
3437 }
3438 
3439 void VM_RedefineClasses::dump_methods() {
3440   int j;
3441   RC_TRACE(0x00004000, ("_old_methods --"));
3442   for (j = 0; j < _old_methods->length(); ++j) {
3443     methodOop m = (methodOop) _old_methods->obj_at(j);
3444     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3445     m->access_flags().print_on(tty);
3446     tty->print(" --  ");
3447     m->print_name(tty);
3448     tty->cr();
3449   }
3450   RC_TRACE(0x00004000, ("_new_methods --"));
3451   for (j = 0; j < _new_methods->length(); ++j) {
3452     methodOop m = (methodOop) _new_methods->obj_at(j);
3453     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3454     m->access_flags().print_on(tty);
3455     tty->print(" --  ");
3456     m->print_name(tty);
3457     tty->cr();
3458   }
3459   RC_TRACE(0x00004000, ("_matching_(old/new)_methods --"));
3460   for (j = 0; j < _matching_methods_length; ++j) {
3461     methodOop m = _matching_old_methods[j];
3462     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3463     m->access_flags().print_on(tty);
3464     tty->print(" --  ");
3465     m->print_name(tty);
3466     tty->cr();
3467     m = _matching_new_methods[j];
3468     RC_TRACE_NO_CR(0x00004000, ("      (%5d)  ", m->vtable_index()));
3469     m->access_flags().print_on(tty);
3470     tty->cr();
3471   }
3472   RC_TRACE(0x00004000, ("_deleted_methods --"));
3473   for (j = 0; j < _deleted_methods_length; ++j) {
3474     methodOop m = _deleted_methods[j];
3475     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3476     m->access_flags().print_on(tty);
3477     tty->print(" --  ");
3478     m->print_name(tty);
3479     tty->cr();
3480   }
3481   RC_TRACE(0x00004000, ("_added_methods --"));
3482   for (j = 0; j < _added_methods_length; ++j) {
3483     methodOop m = _added_methods[j];
3484     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3485     m->access_flags().print_on(tty);
3486     tty->print(" --  ");
3487     m->print_name(tty);
3488     tty->cr();
3489   }
3490 }