< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page




 127   if (_class_defs == NULL) {
 128     _res = JVMTI_ERROR_NULL_POINTER;
 129     return false;
 130   }
 131 
 132   for (int i = 0; i < _class_count; i++) {
 133     if (_class_defs[i].klass == NULL) {
 134       _res = JVMTI_ERROR_INVALID_CLASS;
 135       return false;
 136     }
 137     if (_class_defs[i].class_byte_count == 0) {
 138       _res = JVMTI_ERROR_INVALID_CLASS_FORMAT;
 139       return false;
 140     }
 141     if (_class_defs[i].class_bytes == NULL) {
 142       _res = JVMTI_ERROR_NULL_POINTER;
 143       return false;
 144     }
 145 
 146     oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
 147     // classes for primitives and arrays and vm unsafe anonymous classes cannot be redefined
 148     // check here so following code can assume these classes are InstanceKlass

 149     if (!is_modifiable_class(mirror)) {
 150       _res = JVMTI_ERROR_UNMODIFIABLE_CLASS;
 151       return false;
 152     }
 153   }
 154 
 155   // Start timer after all the sanity checks; not quite accurate, but
 156   // better than adding a bunch of stop() calls.
 157   if (log_is_enabled(Info, redefine, class, timer)) {
 158     _timer_vm_op_prologue.start();
 159   }
 160 
 161   lock_classes();
 162   // We first load new class versions in the prologue, because somewhere down the
 163   // call chain it is required that the current thread is a Java thread.
 164   _res = load_new_class_versions(Thread::current());
 165   if (_res != JVMTI_ERROR_NONE) {
 166     // free any successfully created classes, since none are redefined
 167     for (int i = 0; i < _class_count; i++) {
 168       if (_scratch_classes[i] != NULL) {


 273     log_info(redefine, class, timer)
 274       ("vm_op: all=" JULONG_FORMAT "  prologue=" JULONG_FORMAT "  doit=" JULONG_FORMAT,
 275        all_time, (julong)_timer_vm_op_prologue.milliseconds(), doit_time);
 276     log_info(redefine, class, timer)
 277       ("redefine_single_class: phase1=" JULONG_FORMAT "  phase2=" JULONG_FORMAT,
 278        (julong)_timer_rsc_phase1.milliseconds(), (julong)_timer_rsc_phase2.milliseconds());
 279   }
 280 }
 281 
 282 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
 283   // classes for primitives cannot be redefined
 284   if (java_lang_Class::is_primitive(klass_mirror)) {
 285     return false;
 286   }
 287   Klass* k = java_lang_Class::as_Klass(klass_mirror);
 288   // classes for arrays cannot be redefined
 289   if (k == NULL || !k->is_instance_klass()) {
 290     return false;
 291   }
 292 
 293   // Cannot redefine or retransform an unsafe anonymous class.
 294   if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {

 295     return false;
 296   }
 297   return true;
 298 }
 299 
 300 // Append the current entry at scratch_i in scratch_cp to *merge_cp_p
 301 // where the end of *merge_cp_p is specified by *merge_cp_length_p. For
 302 // direct CP entries, there is just the current entry to append. For
 303 // indirect and double-indirect CP entries, there are zero or more
 304 // referenced CP entries along with the current entry to append.
 305 // Indirect and double-indirect CP entries are handled by recursive
 306 // calls to append_entry() as needed. The referenced CP entries are
 307 // always appended to *merge_cp_p before the referee CP entry. These
 308 // referenced CP entries may already exist in *merge_cp_p in which case
 309 // there is nothing extra to append and only the current entry is
 310 // appended.
 311 void VM_RedefineClasses::append_entry(const constantPoolHandle& scratch_cp,
 312        int scratch_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p,
 313        TRAPS) {
 314 


1159        the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
1160 
1161     ClassFileStream st((u1*)_class_defs[i].class_bytes,
1162                        _class_defs[i].class_byte_count,
1163                        "__VM_RedefineClasses__",
1164                        ClassFileStream::verify);
1165 
1166     // Parse the stream.
1167     Handle the_class_loader(THREAD, the_class->class_loader());
1168     Handle protection_domain(THREAD, the_class->protection_domain());
1169     // Set redefined class handle in JvmtiThreadState class.
1170     // This redefined class is sent to agent event handler for class file
1171     // load hook event.
1172     state->set_class_being_redefined(the_class, _class_load_kind);
1173 
1174     InstanceKlass* scratch_class = SystemDictionary::parse_stream(
1175                                                       the_class_sym,
1176                                                       the_class_loader,
1177                                                       protection_domain,
1178                                                       &st,

1179                                                       THREAD);
1180     // Clear class_being_redefined just to be sure.
1181     state->clear_class_being_redefined();
1182 
1183     // TODO: if this is retransform, and nothing changed we can skip it
1184 
1185     // Need to clean up allocated InstanceKlass if there's an error so assign
1186     // the result here. Caller deallocates all the scratch classes in case of
1187     // an error.
1188     _scratch_classes[i] = scratch_class;
1189 
1190     if (HAS_PENDING_EXCEPTION) {
1191       Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
1192       log_info(redefine, class, load, exceptions)("parse_stream exception: '%s'", ex_name->as_C_string());
1193       CLEAR_PENDING_EXCEPTION;
1194 
1195       if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
1196         return JVMTI_ERROR_UNSUPPORTED_VERSION;
1197       } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
1198         return JVMTI_ERROR_INVALID_CLASS_FORMAT;




 127   if (_class_defs == NULL) {
 128     _res = JVMTI_ERROR_NULL_POINTER;
 129     return false;
 130   }
 131 
 132   for (int i = 0; i < _class_count; i++) {
 133     if (_class_defs[i].klass == NULL) {
 134       _res = JVMTI_ERROR_INVALID_CLASS;
 135       return false;
 136     }
 137     if (_class_defs[i].class_byte_count == 0) {
 138       _res = JVMTI_ERROR_INVALID_CLASS_FORMAT;
 139       return false;
 140     }
 141     if (_class_defs[i].class_bytes == NULL) {
 142       _res = JVMTI_ERROR_NULL_POINTER;
 143       return false;
 144     }
 145 
 146     oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
 147     // classes for primitives, arrays, nonfindable and vm unsafe anonymous classes
 148     // cannot be redefined.  Check here so following code can assume these classes
 149     // are InstanceKlass.
 150     if (!is_modifiable_class(mirror)) {
 151       _res = JVMTI_ERROR_UNMODIFIABLE_CLASS;
 152       return false;
 153     }
 154   }
 155 
 156   // Start timer after all the sanity checks; not quite accurate, but
 157   // better than adding a bunch of stop() calls.
 158   if (log_is_enabled(Info, redefine, class, timer)) {
 159     _timer_vm_op_prologue.start();
 160   }
 161 
 162   lock_classes();
 163   // We first load new class versions in the prologue, because somewhere down the
 164   // call chain it is required that the current thread is a Java thread.
 165   _res = load_new_class_versions(Thread::current());
 166   if (_res != JVMTI_ERROR_NONE) {
 167     // free any successfully created classes, since none are redefined
 168     for (int i = 0; i < _class_count; i++) {
 169       if (_scratch_classes[i] != NULL) {


 274     log_info(redefine, class, timer)
 275       ("vm_op: all=" JULONG_FORMAT "  prologue=" JULONG_FORMAT "  doit=" JULONG_FORMAT,
 276        all_time, (julong)_timer_vm_op_prologue.milliseconds(), doit_time);
 277     log_info(redefine, class, timer)
 278       ("redefine_single_class: phase1=" JULONG_FORMAT "  phase2=" JULONG_FORMAT,
 279        (julong)_timer_rsc_phase1.milliseconds(), (julong)_timer_rsc_phase2.milliseconds());
 280   }
 281 }
 282 
 283 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
 284   // classes for primitives cannot be redefined
 285   if (java_lang_Class::is_primitive(klass_mirror)) {
 286     return false;
 287   }
 288   Klass* k = java_lang_Class::as_Klass(klass_mirror);
 289   // classes for arrays cannot be redefined
 290   if (k == NULL || !k->is_instance_klass()) {
 291     return false;
 292   }
 293 
 294   // Cannot redefine or retransform a nonfindable or an unsafe anonymous class.
 295   if (InstanceKlass::cast(k)->is_nonfindable() ||
 296       InstanceKlass::cast(k)->is_unsafe_anonymous()) {
 297     return false;
 298   }
 299   return true;
 300 }
 301 
 302 // Append the current entry at scratch_i in scratch_cp to *merge_cp_p
 303 // where the end of *merge_cp_p is specified by *merge_cp_length_p. For
 304 // direct CP entries, there is just the current entry to append. For
 305 // indirect and double-indirect CP entries, there are zero or more
 306 // referenced CP entries along with the current entry to append.
 307 // Indirect and double-indirect CP entries are handled by recursive
 308 // calls to append_entry() as needed. The referenced CP entries are
 309 // always appended to *merge_cp_p before the referee CP entry. These
 310 // referenced CP entries may already exist in *merge_cp_p in which case
 311 // there is nothing extra to append and only the current entry is
 312 // appended.
 313 void VM_RedefineClasses::append_entry(const constantPoolHandle& scratch_cp,
 314        int scratch_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p,
 315        TRAPS) {
 316 


1161        the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
1162 
1163     ClassFileStream st((u1*)_class_defs[i].class_bytes,
1164                        _class_defs[i].class_byte_count,
1165                        "__VM_RedefineClasses__",
1166                        ClassFileStream::verify);
1167 
1168     // Parse the stream.
1169     Handle the_class_loader(THREAD, the_class->class_loader());
1170     Handle protection_domain(THREAD, the_class->protection_domain());
1171     // Set redefined class handle in JvmtiThreadState class.
1172     // This redefined class is sent to agent event handler for class file
1173     // load hook event.
1174     state->set_class_being_redefined(the_class, _class_load_kind);
1175 
1176     InstanceKlass* scratch_class = SystemDictionary::parse_stream(
1177                                                       the_class_sym,
1178                                                       the_class_loader,
1179                                                       protection_domain,
1180                                                       &st,
1181                                                       NULL, // dynamic_nest_host
1182                                                       THREAD);
1183     // Clear class_being_redefined just to be sure.
1184     state->clear_class_being_redefined();
1185 
1186     // TODO: if this is retransform, and nothing changed we can skip it
1187 
1188     // Need to clean up allocated InstanceKlass if there's an error so assign
1189     // the result here. Caller deallocates all the scratch classes in case of
1190     // an error.
1191     _scratch_classes[i] = scratch_class;
1192 
1193     if (HAS_PENDING_EXCEPTION) {
1194       Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
1195       log_info(redefine, class, load, exceptions)("parse_stream exception: '%s'", ex_name->as_C_string());
1196       CLEAR_PENDING_EXCEPTION;
1197 
1198       if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
1199         return JVMTI_ERROR_UNSUPPORTED_VERSION;
1200       } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
1201         return JVMTI_ERROR_INVALID_CLASS_FORMAT;


< prev index next >