< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page




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


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

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


1148     InstanceKlass* the_class = get_ik(_class_defs[i].klass);
1149     Symbol*  the_class_sym = the_class->name();
1150 
1151     log_debug(redefine, class, load)
1152       ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)",
1153        the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
1154 
1155     ClassFileStream st((u1*)_class_defs[i].class_bytes,
1156                        _class_defs[i].class_byte_count,
1157                        "__VM_RedefineClasses__",
1158                        ClassFileStream::verify);
1159 
1160     // Parse the stream.
1161     Handle the_class_loader(THREAD, the_class->class_loader());
1162     Handle protection_domain(THREAD, the_class->protection_domain());
1163     // Set redefined class handle in JvmtiThreadState class.
1164     // This redefined class is sent to agent event handler for class file
1165     // load hook event.
1166     state->set_class_being_redefined(the_class, _class_load_kind);
1167 

1168     InstanceKlass* scratch_class = SystemDictionary::parse_stream(
1169                                                       the_class_sym,
1170                                                       the_class_loader,
1171                                                       protection_domain,
1172                                                       &st,

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




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


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


1150     InstanceKlass* the_class = get_ik(_class_defs[i].klass);
1151     Symbol*  the_class_sym = the_class->name();
1152 
1153     log_debug(redefine, class, load)
1154       ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)",
1155        the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
1156 
1157     ClassFileStream st((u1*)_class_defs[i].class_bytes,
1158                        _class_defs[i].class_byte_count,
1159                        "__VM_RedefineClasses__",
1160                        ClassFileStream::verify);
1161 
1162     // Parse the stream.
1163     Handle the_class_loader(THREAD, the_class->class_loader());
1164     Handle protection_domain(THREAD, the_class->protection_domain());
1165     // Set redefined class handle in JvmtiThreadState class.
1166     // This redefined class is sent to agent event handler for class file
1167     // load hook event.
1168     state->set_class_being_redefined(the_class, _class_load_kind);
1169 
1170     ClassLoadInfo cl_info(protection_domain);
1171     InstanceKlass* scratch_class = SystemDictionary::parse_stream(
1172                                                       the_class_sym,
1173                                                       the_class_loader,

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


< prev index next >