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,


3334   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
3335   java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
3336 
3337   if (class_oop != _the_class_oop) {
3338     // _the_class_oop count is printed at end of redefine_single_class()
3339     RC_TRACE_WITH_THREAD(0x00000008, THREAD,
3340       ("updated count in subclass=%s to %d", ik->external_name(), new_count));
3341   }
3342 
3343   for (Klass *subk = ik->subklass(); subk != NULL;
3344        subk = subk->next_sibling()) {
3345     if (subk->oop_is_instance()) {
3346       // Only update instanceKlasses
3347       instanceKlass *subik = (instanceKlass*)subk;
3348       // recursively do subclasses of the current subclass
3349       increment_class_counter(subik, THREAD);
3350     }
3351   }
3352 }
3353 
3354 #ifndef PRODUCT
3355 void VM_RedefineClasses::check_class(klassOop k_oop,
3356        oop initiating_loader, TRAPS) {
3357   Klass *k = k_oop->klass_part();
3358   if (k->oop_is_instance()) {
3359     HandleMark hm(THREAD);
3360     instanceKlass *ik = (instanceKlass *) k;
3361 
3362     if (ik->vtable_length() > 0) {
3363       ResourceMark rm(THREAD);
3364       if (!ik->vtable()->check_no_old_entries()) {
3365         tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());







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

































3367         dump_methods();
3368         assert(false, "OLD method found");


3369       }

3370     }
3371   }
3372 }
3373 
3374 void VM_RedefineClasses::dump_methods() {
3375         int j;
3376         tty->print_cr("_old_methods --");
3377         for (j = 0; j < _old_methods->length(); ++j) {
3378           methodOop m = (methodOop) _old_methods->obj_at(j);
3379           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3380           m->access_flags().print_on(tty);
3381           tty->print(" --  ");
3382           m->print_name(tty);
3383           tty->cr();
3384         }
3385         tty->print_cr("_new_methods --");
3386         for (j = 0; j < _new_methods->length(); ++j) {
3387           methodOop m = (methodOop) _new_methods->obj_at(j);
3388           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3389           m->access_flags().print_on(tty);
3390           tty->print(" --  ");
3391           m->print_name(tty);
3392           tty->cr();
3393         }
3394         tty->print_cr("_matching_(old/new)_methods --");
3395         for (j = 0; j < _matching_methods_length; ++j) {
3396           methodOop m = _matching_old_methods[j];
3397           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3398           m->access_flags().print_on(tty);
3399           tty->print(" --  ");
3400           m->print_name(tty);
3401           tty->cr();
3402           m = _matching_new_methods[j];
3403           tty->print("      (%5d)  ", m->vtable_index());
3404           m->access_flags().print_on(tty);
3405           tty->cr();
3406         }
3407         tty->print_cr("_deleted_methods --");
3408         for (j = 0; j < _deleted_methods_length; ++j) {
3409           methodOop m = _deleted_methods[j];
3410           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3411           m->access_flags().print_on(tty);
3412           tty->print(" --  ");
3413           m->print_name(tty);
3414           tty->cr();
3415         }
3416         tty->print_cr("_added_methods --");
3417         for (j = 0; j < _added_methods_length; ++j) {
3418           methodOop m = _added_methods[j];
3419           tty->print("%4d  (%5d)  ", j, m->vtable_index());
3420           m->access_flags().print_on(tty);
3421           tty->print(" --  ");
3422           m->print_name(tty);
3423           tty->cr();
3424         }
3425 }
3426 #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,


3341   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
3342   java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
3343 
3344   if (class_oop != _the_class_oop) {
3345     // _the_class_oop count is printed at end of redefine_single_class()
3346     RC_TRACE_WITH_THREAD(0x00000008, THREAD,
3347       ("updated count in subclass=%s to %d", ik->external_name(), new_count));
3348   }
3349 
3350   for (Klass *subk = ik->subklass(); subk != NULL;
3351        subk = subk->next_sibling()) {
3352     if (subk->oop_is_instance()) {
3353       // Only update instanceKlasses
3354       instanceKlass *subik = (instanceKlass*)subk;
3355       // recursively do subclasses of the current subclass
3356       increment_class_counter(subik, THREAD);
3357     }
3358   }
3359 }
3360 

3361 void VM_RedefineClasses::check_class(klassOop k_oop,
3362        oop initiating_loader, TRAPS) {
3363   Klass *k = k_oop->klass_part();
3364   if (k->oop_is_instance()) {
3365     HandleMark hm(THREAD);
3366     instanceKlass *ik = (instanceKlass *) k;
3367     bool no_old_methods = true;  // be optimistic

3368     ResourceMark rm(THREAD);
3369 
3370     // a vtable should never contain old or obsolete methods
3371     if (ik->vtable_length() > 0 &&
3372         !ik->vtable()->check_no_old_or_obsolete_entries()) {
3373       if (RC_TRACE_ENABLED(0x00004000)) {
3374         RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3375           ("klassVtable::check_no_old_or_obsolete_entries failure"
3376            " -- OLD or OBSOLETE method found -- class: %s",
3377            ik->signature_name()));
3378         ik->vtable()->dump_vtable();
3379       }
3380       no_old_methods = false;
3381     }
3382 
3383     // an itable should never contain old or obsolete methods
3384     if (ik->itable_length() > 0 &&
3385         !ik->itable()->check_no_old_or_obsolete_entries()) {
3386       if (RC_TRACE_ENABLED(0x00004000)) {
3387         RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3388           ("klassItable::check_no_old_or_obsolete_entries failure"
3389            " -- OLD or OBSOLETE method found -- class: %s",
3390            ik->signature_name()));
3391         ik->itable()->dump_itable();
3392       }
3393       no_old_methods = false;
3394     }
3395 
3396     // the constant pool cache should never contain old or obsolete methods
3397     if (ik->constants() != NULL &&
3398         ik->constants()->cache() != NULL &&
3399         !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
3400       if (RC_TRACE_ENABLED(0x00004000)) {
3401         RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3402           ("cp-cache::check_no_old_or_obsolete_entries failure"
3403            " -- OLD or OBSOLETE method found -- class: %s",
3404            ik->signature_name()));
3405         ik->constants()->cache()->dump_cache();
3406       }
3407       no_old_methods = false;
3408     }
3409 
3410     if (!no_old_methods) {
3411       if (RC_TRACE_ENABLED(0x00004000)) {
3412         dump_methods();
3413       } else {
3414         tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
3415           "to see more info about the following guarantee() failure.");
3416       }
3417       guarantee(false, "OLD and/or OBSOLETE method(s) found");
3418     }
3419   }
3420 }
3421 
3422 void VM_RedefineClasses::dump_methods() {
3423   int j;
3424   RC_TRACE(0x00004000, ("_old_methods --"));
3425   for (j = 0; j < _old_methods->length(); ++j) {
3426     methodOop m = (methodOop) _old_methods->obj_at(j);
3427     RC_TRACE_NO_CR(0x00004000, ("%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   RC_TRACE(0x00004000, ("_new_methods --"));
3434   for (j = 0; j < _new_methods->length(); ++j) {
3435     methodOop m = (methodOop) _new_methods->obj_at(j);
3436     RC_TRACE_NO_CR(0x00004000, ("%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   RC_TRACE(0x00004000, ("_matching_(old/new)_methods --"));
3443   for (j = 0; j < _matching_methods_length; ++j) {
3444     methodOop m = _matching_old_methods[j];
3445     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3446     m->access_flags().print_on(tty);
3447     tty->print(" --  ");
3448     m->print_name(tty);
3449     tty->cr();
3450     m = _matching_new_methods[j];
3451     RC_TRACE_NO_CR(0x00004000, ("      (%5d)  ", m->vtable_index()));
3452     m->access_flags().print_on(tty);
3453     tty->cr();
3454   }
3455   RC_TRACE(0x00004000, ("_deleted_methods --"));
3456   for (j = 0; j < _deleted_methods_length; ++j) {
3457     methodOop m = _deleted_methods[j];
3458     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3459     m->access_flags().print_on(tty);
3460     tty->print(" --  ");
3461     m->print_name(tty);
3462     tty->cr();
3463   }
3464   RC_TRACE(0x00004000, ("_added_methods --"));
3465   for (j = 0; j < _added_methods_length; ++j) {
3466     methodOop m = _added_methods[j];
3467     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
3468     m->access_flags().print_on(tty);
3469     tty->print(" --  ");
3470     m->print_name(tty);
3471     tty->cr();
3472   }
3473 }