< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com


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

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


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

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


1222     InstanceKlass* the_class = get_ik(_class_defs[i].klass);
1223     Symbol*  the_class_sym = the_class->name();
1224 
1225     log_debug(redefine, class, load)
1226       ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)",
1227        the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
1228 
1229     ClassFileStream st((u1*)_class_defs[i].class_bytes,
1230                        _class_defs[i].class_byte_count,
1231                        "__VM_RedefineClasses__",
1232                        ClassFileStream::verify);
1233 
1234     // Parse the stream.
1235     Handle the_class_loader(THREAD, the_class->class_loader());
1236     Handle protection_domain(THREAD, the_class->protection_domain());
1237     // Set redefined class handle in JvmtiThreadState class.
1238     // This redefined class is sent to agent event handler for class file
1239     // load hook event.
1240     state->set_class_being_redefined(the_class, _class_load_kind);
1241 

1242     InstanceKlass* scratch_class = SystemDictionary::parse_stream(
1243                                                       the_class_sym,
1244                                                       the_class_loader,
1245                                                       protection_domain,
1246                                                       &st,

1247                                                       THREAD);
1248     // Clear class_being_redefined just to be sure.
1249     state->clear_class_being_redefined();
1250 
1251     // TODO: if this is retransform, and nothing changed we can skip it
1252 
1253     // Need to clean up allocated InstanceKlass if there's an error so assign
1254     // the result here. Caller deallocates all the scratch classes in case of
1255     // an error.
1256     _scratch_classes[i] = scratch_class;
1257 
1258     if (HAS_PENDING_EXCEPTION) {
1259       Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
1260       log_info(redefine, class, load, exceptions)("parse_stream exception: '%s'", ex_name->as_C_string());
1261       CLEAR_PENDING_EXCEPTION;
1262 
1263       if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
1264         return JVMTI_ERROR_UNSUPPORTED_VERSION;
1265       } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
1266         return JVMTI_ERROR_INVALID_CLASS_FORMAT;




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


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


1224     InstanceKlass* the_class = get_ik(_class_defs[i].klass);
1225     Symbol*  the_class_sym = the_class->name();
1226 
1227     log_debug(redefine, class, load)
1228       ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)",
1229        the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
1230 
1231     ClassFileStream st((u1*)_class_defs[i].class_bytes,
1232                        _class_defs[i].class_byte_count,
1233                        "__VM_RedefineClasses__",
1234                        ClassFileStream::verify);
1235 
1236     // Parse the stream.
1237     Handle the_class_loader(THREAD, the_class->class_loader());
1238     Handle protection_domain(THREAD, the_class->protection_domain());
1239     // Set redefined class handle in JvmtiThreadState class.
1240     // This redefined class is sent to agent event handler for class file
1241     // load hook event.
1242     state->set_class_being_redefined(the_class, _class_load_kind);
1243 
1244     ClassLoadInfo cl_info(protection_domain);
1245     InstanceKlass* scratch_class = SystemDictionary::parse_stream(
1246                                                       the_class_sym,
1247                                                       the_class_loader,

1248                                                       &st,
1249                                                       cl_info,
1250                                                       THREAD);
1251     // Clear class_being_redefined just to be sure.
1252     state->clear_class_being_redefined();
1253 
1254     // TODO: if this is retransform, and nothing changed we can skip it
1255 
1256     // Need to clean up allocated InstanceKlass if there's an error so assign
1257     // the result here. Caller deallocates all the scratch classes in case of
1258     // an error.
1259     _scratch_classes[i] = scratch_class;
1260 
1261     if (HAS_PENDING_EXCEPTION) {
1262       Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
1263       log_info(redefine, class, load, exceptions)("parse_stream exception: '%s'", ex_name->as_C_string());
1264       CLEAR_PENDING_EXCEPTION;
1265 
1266       if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
1267         return JVMTI_ERROR_UNSUPPORTED_VERSION;
1268       } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
1269         return JVMTI_ERROR_INVALID_CLASS_FORMAT;


< prev index next >