src/share/vm/prims/jvmtiRedefineClasses.cpp

Print this page




  25 #include "precompiled.hpp"
  26 #include "classfile/metadataOnStackMark.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "classfile/verifier.hpp"
  29 #include "code/codeCache.hpp"
  30 #include "compiler/compileBroker.hpp"
  31 #include "interpreter/oopMapCache.hpp"
  32 #include "interpreter/rewriter.hpp"
  33 #include "memory/gcLocker.hpp"
  34 #include "memory/metadataFactory.hpp"
  35 #include "memory/metaspaceShared.hpp"
  36 #include "memory/universe.inline.hpp"
  37 #include "oops/fieldStreams.hpp"
  38 #include "oops/klassVtable.hpp"
  39 #include "prims/jvmtiImpl.hpp"
  40 #include "prims/jvmtiRedefineClasses.hpp"
  41 #include "prims/methodComparator.hpp"
  42 #include "runtime/deoptimization.hpp"
  43 #include "runtime/relocator.hpp"
  44 #include "utilities/bitMap.inline.hpp"

  45 
  46 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  47 
  48 Array<Method*>* VM_RedefineClasses::_old_methods = NULL;
  49 Array<Method*>* VM_RedefineClasses::_new_methods = NULL;
  50 Method**  VM_RedefineClasses::_matching_old_methods = NULL;
  51 Method**  VM_RedefineClasses::_matching_new_methods = NULL;
  52 Method**  VM_RedefineClasses::_deleted_methods      = NULL;
  53 Method**  VM_RedefineClasses::_added_methods        = NULL;
  54 int         VM_RedefineClasses::_matching_methods_length = 0;
  55 int         VM_RedefineClasses::_deleted_methods_length  = 0;
  56 int         VM_RedefineClasses::_added_methods_length    = 0;
  57 Klass*      VM_RedefineClasses::_the_class_oop = NULL;
  58 
  59 
  60 VM_RedefineClasses::VM_RedefineClasses(jint class_count,
  61                                        const jvmtiClassDefinition *class_defs,
  62                                        JvmtiClassLoadKind class_load_kind) {
  63   _class_count = class_count;
  64   _class_defs = class_defs;


 155   // See jvmtiExport.hpp for detailed explanation.
 156   JvmtiExport::set_has_redefined_a_class();
 157 
 158 // check_class() is optionally called for product bits, but is
 159 // always called for non-product bits.
 160 #ifdef PRODUCT
 161   if (RC_TRACE_ENABLED(0x00004000)) {
 162 #endif
 163     RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
 164     CheckClass check_class(thread);
 165     ClassLoaderDataGraph::classes_do(&check_class);
 166 #ifdef PRODUCT
 167   }
 168 #endif
 169 }
 170 
 171 void VM_RedefineClasses::doit_epilogue() {
 172   // Free os::malloc allocated memory.
 173   os::free(_scratch_classes);
 174 



 175   if (RC_TRACE_ENABLED(0x00000004)) {
 176     // Used to have separate timers for "doit" and "all", but the timer
 177     // overhead skewed the measurements.
 178     jlong doit_time = _timer_rsc_phase1.milliseconds() +
 179                       _timer_rsc_phase2.milliseconds();
 180     jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
 181 
 182     RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
 183       "  prologue=" UINT64_FORMAT "  doit=" UINT64_FORMAT, all_time,
 184       _timer_vm_op_prologue.milliseconds(), doit_time));
 185     RC_TRACE(0x00000004,
 186       ("redefine_single_class: phase1=" UINT64_FORMAT "  phase2=" UINT64_FORMAT,
 187        _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()));
 188   }
 189 }
 190 
 191 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
 192   // classes for primitives cannot be redefined
 193   if (java_lang_Class::is_primitive(klass_mirror)) {
 194     return false;


4079     mnt->adjust_method_entries(the_class(), &trace_name_printed);
4080   }
4081 
4082   if (the_class->oop_map_cache() != NULL) {
4083     // Flush references to any obsolete methods from the oop map cache
4084     // so that obsolete methods are not pinned.
4085     the_class->oop_map_cache()->flush_obsolete_entries();
4086   }
4087 
4088   // increment the classRedefinedCount field in the_class and in any
4089   // direct and indirect subclasses of the_class
4090   increment_class_counter((InstanceKlass *)the_class(), THREAD);
4091 
4092   // RC_TRACE macro has an embedded ResourceMark
4093   RC_TRACE_WITH_THREAD(0x00000001, THREAD,
4094     ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
4095     the_class->external_name(),
4096     java_lang_Class::classRedefinedCount(the_class_mirror),
4097     os::available_memory() >> 10));
4098 







4099   RC_TIMER_STOP(_timer_rsc_phase2);
4100 } // end redefine_single_class()
4101 
4102 
4103 // Increment the classRedefinedCount field in the specific InstanceKlass
4104 // and in all direct and indirect subclasses.
4105 void VM_RedefineClasses::increment_class_counter(InstanceKlass *ik, TRAPS) {
4106   oop class_mirror = ik->java_mirror();
4107   Klass* class_oop = java_lang_Class::as_Klass(class_mirror);
4108   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
4109   java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
4110 
4111   if (class_oop != _the_class_oop) {
4112     // _the_class_oop count is printed at end of redefine_single_class()
4113     RC_TRACE_WITH_THREAD(0x00000008, THREAD,
4114       ("updated count in subclass=%s to %d", ik->external_name(), new_count));
4115   }
4116 
4117   for (Klass *subk = ik->subklass(); subk != NULL;
4118        subk = subk->next_sibling()) {


4223   }
4224   RC_TRACE(0x00004000, ("_deleted_methods --"));
4225   for (j = 0; j < _deleted_methods_length; ++j) {
4226     Method* m = _deleted_methods[j];
4227     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
4228     m->access_flags().print_on(tty);
4229     tty->print(" --  ");
4230     m->print_name(tty);
4231     tty->cr();
4232   }
4233   RC_TRACE(0x00004000, ("_added_methods --"));
4234   for (j = 0; j < _added_methods_length; ++j) {
4235     Method* m = _added_methods[j];
4236     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
4237     m->access_flags().print_on(tty);
4238     tty->print(" --  ");
4239     m->print_name(tty);
4240     tty->cr();
4241   }
4242 }










  25 #include "precompiled.hpp"
  26 #include "classfile/metadataOnStackMark.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "classfile/verifier.hpp"
  29 #include "code/codeCache.hpp"
  30 #include "compiler/compileBroker.hpp"
  31 #include "interpreter/oopMapCache.hpp"
  32 #include "interpreter/rewriter.hpp"
  33 #include "memory/gcLocker.hpp"
  34 #include "memory/metadataFactory.hpp"
  35 #include "memory/metaspaceShared.hpp"
  36 #include "memory/universe.inline.hpp"
  37 #include "oops/fieldStreams.hpp"
  38 #include "oops/klassVtable.hpp"
  39 #include "prims/jvmtiImpl.hpp"
  40 #include "prims/jvmtiRedefineClasses.hpp"
  41 #include "prims/methodComparator.hpp"
  42 #include "runtime/deoptimization.hpp"
  43 #include "runtime/relocator.hpp"
  44 #include "utilities/bitMap.inline.hpp"
  45 #include "utilities/events.hpp"
  46 
  47 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  48 
  49 Array<Method*>* VM_RedefineClasses::_old_methods = NULL;
  50 Array<Method*>* VM_RedefineClasses::_new_methods = NULL;
  51 Method**  VM_RedefineClasses::_matching_old_methods = NULL;
  52 Method**  VM_RedefineClasses::_matching_new_methods = NULL;
  53 Method**  VM_RedefineClasses::_deleted_methods      = NULL;
  54 Method**  VM_RedefineClasses::_added_methods        = NULL;
  55 int         VM_RedefineClasses::_matching_methods_length = 0;
  56 int         VM_RedefineClasses::_deleted_methods_length  = 0;
  57 int         VM_RedefineClasses::_added_methods_length    = 0;
  58 Klass*      VM_RedefineClasses::_the_class_oop = NULL;
  59 
  60 
  61 VM_RedefineClasses::VM_RedefineClasses(jint class_count,
  62                                        const jvmtiClassDefinition *class_defs,
  63                                        JvmtiClassLoadKind class_load_kind) {
  64   _class_count = class_count;
  65   _class_defs = class_defs;


 156   // See jvmtiExport.hpp for detailed explanation.
 157   JvmtiExport::set_has_redefined_a_class();
 158 
 159 // check_class() is optionally called for product bits, but is
 160 // always called for non-product bits.
 161 #ifdef PRODUCT
 162   if (RC_TRACE_ENABLED(0x00004000)) {
 163 #endif
 164     RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
 165     CheckClass check_class(thread);
 166     ClassLoaderDataGraph::classes_do(&check_class);
 167 #ifdef PRODUCT
 168   }
 169 #endif
 170 }
 171 
 172 void VM_RedefineClasses::doit_epilogue() {
 173   // Free os::malloc allocated memory.
 174   os::free(_scratch_classes);
 175 
 176   // Reset the_class_oop to null for error printing.
 177   _the_class_oop = NULL;
 178 
 179   if (RC_TRACE_ENABLED(0x00000004)) {
 180     // Used to have separate timers for "doit" and "all", but the timer
 181     // overhead skewed the measurements.
 182     jlong doit_time = _timer_rsc_phase1.milliseconds() +
 183                       _timer_rsc_phase2.milliseconds();
 184     jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
 185 
 186     RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
 187       "  prologue=" UINT64_FORMAT "  doit=" UINT64_FORMAT, all_time,
 188       _timer_vm_op_prologue.milliseconds(), doit_time));
 189     RC_TRACE(0x00000004,
 190       ("redefine_single_class: phase1=" UINT64_FORMAT "  phase2=" UINT64_FORMAT,
 191        _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()));
 192   }
 193 }
 194 
 195 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
 196   // classes for primitives cannot be redefined
 197   if (java_lang_Class::is_primitive(klass_mirror)) {
 198     return false;


4083     mnt->adjust_method_entries(the_class(), &trace_name_printed);
4084   }
4085 
4086   if (the_class->oop_map_cache() != NULL) {
4087     // Flush references to any obsolete methods from the oop map cache
4088     // so that obsolete methods are not pinned.
4089     the_class->oop_map_cache()->flush_obsolete_entries();
4090   }
4091 
4092   // increment the classRedefinedCount field in the_class and in any
4093   // direct and indirect subclasses of the_class
4094   increment_class_counter((InstanceKlass *)the_class(), THREAD);
4095 
4096   // RC_TRACE macro has an embedded ResourceMark
4097   RC_TRACE_WITH_THREAD(0x00000001, THREAD,
4098     ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
4099     the_class->external_name(),
4100     java_lang_Class::classRedefinedCount(the_class_mirror),
4101     os::available_memory() >> 10));
4102 
4103   {
4104     ResourceMark rm(THREAD);
4105     Events::log_redefinition(THREAD, "redefined class name=%s, count=%d",
4106                              the_class->external_name(),
4107                              java_lang_Class::classRedefinedCount(the_class_mirror));
4108 
4109   }
4110   RC_TIMER_STOP(_timer_rsc_phase2);
4111 } // end redefine_single_class()
4112 
4113 
4114 // Increment the classRedefinedCount field in the specific InstanceKlass
4115 // and in all direct and indirect subclasses.
4116 void VM_RedefineClasses::increment_class_counter(InstanceKlass *ik, TRAPS) {
4117   oop class_mirror = ik->java_mirror();
4118   Klass* class_oop = java_lang_Class::as_Klass(class_mirror);
4119   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
4120   java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
4121 
4122   if (class_oop != _the_class_oop) {
4123     // _the_class_oop count is printed at end of redefine_single_class()
4124     RC_TRACE_WITH_THREAD(0x00000008, THREAD,
4125       ("updated count in subclass=%s to %d", ik->external_name(), new_count));
4126   }
4127 
4128   for (Klass *subk = ik->subklass(); subk != NULL;
4129        subk = subk->next_sibling()) {


4234   }
4235   RC_TRACE(0x00004000, ("_deleted_methods --"));
4236   for (j = 0; j < _deleted_methods_length; ++j) {
4237     Method* m = _deleted_methods[j];
4238     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
4239     m->access_flags().print_on(tty);
4240     tty->print(" --  ");
4241     m->print_name(tty);
4242     tty->cr();
4243   }
4244   RC_TRACE(0x00004000, ("_added_methods --"));
4245   for (j = 0; j < _added_methods_length; ++j) {
4246     Method* m = _added_methods[j];
4247     RC_TRACE_NO_CR(0x00004000, ("%4d  (%5d)  ", j, m->vtable_index()));
4248     m->access_flags().print_on(tty);
4249     tty->print(" --  ");
4250     m->print_name(tty);
4251     tty->cr();
4252   }
4253 }
4254 
4255 void VM_RedefineClasses::print_on_error(outputStream* st) const {
4256   VM_Operation::print_on_error(st);
4257   if (_the_class_oop != NULL) {
4258     ResourceMark rm;
4259     st->print_cr(", redefining class %s", _the_class_oop->external_name());
4260   }
4261 }