< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page

        

*** 88,124 **** } // If any of the classes are being redefined, wait // Parallel constant pool merging leads to indeterminate constant pools. void VM_RedefineClasses::lock_classes() { ! MonitorLocker ml(RedefineClasses_lock); bool has_redefined; do { has_redefined = false; // Go through classes each time until none are being redefined. for (int i = 0; i < _class_count; i++) { if (get_ik(_class_defs[i].klass)->is_being_redefined()) { ! ml.wait(); has_redefined = true; break; // for loop } } } while (has_redefined); for (int i = 0; i < _class_count; i++) { get_ik(_class_defs[i].klass)->set_is_being_redefined(true); } ! ml.notify_all(); } void VM_RedefineClasses::unlock_classes() { ! MonitorLocker ml(RedefineClasses_lock); for (int i = 0; i < _class_count; i++) { assert(get_ik(_class_defs[i].klass)->is_being_redefined(), "should be being redefined to get here"); get_ik(_class_defs[i].klass)->set_is_being_redefined(false); } ! ml.notify_all(); } bool VM_RedefineClasses::doit_prologue() { if (_class_count == 0) { _res = JVMTI_ERROR_NONE; --- 88,124 ---- } // If any of the classes are being redefined, wait // Parallel constant pool merging leads to indeterminate constant pools. void VM_RedefineClasses::lock_classes() { ! MutexLocker ml(RedefineClasses_lock); bool has_redefined; do { has_redefined = false; // Go through classes each time until none are being redefined. for (int i = 0; i < _class_count; i++) { if (get_ik(_class_defs[i].klass)->is_being_redefined()) { ! RedefineClasses_lock->wait(); has_redefined = true; break; // for loop } } } while (has_redefined); for (int i = 0; i < _class_count; i++) { get_ik(_class_defs[i].klass)->set_is_being_redefined(true); } ! RedefineClasses_lock->notify_all(); } void VM_RedefineClasses::unlock_classes() { ! MutexLocker ml(RedefineClasses_lock); for (int i = 0; i < _class_count; i++) { assert(get_ik(_class_defs[i].klass)->is_being_redefined(), "should be being redefined to get here"); get_ik(_class_defs[i].klass)->set_is_being_redefined(false); } ! RedefineClasses_lock->notify_all(); } bool VM_RedefineClasses::doit_prologue() { if (_class_count == 0) { _res = JVMTI_ERROR_NONE;
*** 142,153 **** _res = JVMTI_ERROR_NULL_POINTER; return false; } oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); ! // classes for primitives and arrays and vm unsafe anonymous classes cannot be redefined ! // check here so following code can assume these classes are InstanceKlass if (!is_modifiable_class(mirror)) { _res = JVMTI_ERROR_UNMODIFIABLE_CLASS; return false; } } --- 142,154 ---- _res = JVMTI_ERROR_NULL_POINTER; return false; } oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); ! // classes for primitives, arrays, nonfindable and vm unsafe anonymous classes ! // cannot be redefined. Check here so following code can assume these classes ! // are InstanceKlass. if (!is_modifiable_class(mirror)) { _res = JVMTI_ERROR_UNMODIFIABLE_CLASS; return false; } }
*** 288,299 **** // classes for arrays cannot be redefined if (k == NULL || !k->is_instance_klass()) { return false; } ! // Cannot redefine or retransform an unsafe anonymous class. ! if (InstanceKlass::cast(k)->is_unsafe_anonymous()) { return false; } return true; } --- 289,301 ---- // classes for arrays cannot be redefined if (k == NULL || !k->is_instance_klass()) { return false; } ! // Cannot redefine or retransform a nonfindable or an unsafe anonymous class. ! if (InstanceKlass::cast(k)->is_nonfindable() || ! InstanceKlass::cast(k)->is_unsafe_anonymous()) { return false; } return true; }
*** 785,800 **** } return JVMTI_ERROR_NONE; } - static bool can_add_or_delete(Method* m) { - // Compatibility mode - return (AllowRedefinitionToAddDeleteMethods && - (m->is_private() && (m->is_static() || m->is_final()))); - } - jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( InstanceKlass* the_class, InstanceKlass* scratch_class) { int i; --- 787,796 ----
*** 996,1006 **** ++oi; ++ni; break; case added: // method added, see if it is OK ! if (!can_add_or_delete(k_new_method)) { return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED; } { u2 num = the_class->next_method_idnum(); if (num == ConstMethod::UNSET_IDNUM) { --- 992,1007 ---- ++oi; ++ni; break; case added: // method added, see if it is OK ! new_flags = (jushort) k_new_method->access_flags().get_flags(); ! if ((new_flags & JVM_ACC_PRIVATE) == 0 ! // hack: private should be treated as final, but alas ! || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 ! ) { ! // new methods must be private return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED; } { u2 num = the_class->next_method_idnum(); if (num == ConstMethod::UNSET_IDNUM) {
*** 1025,1035 **** ("Method added: new: %s [%d]", k_new_method->name_and_sig_as_C_string(), ni); ++ni; // advance to next new method break; case deleted: // method deleted, see if it is OK ! if (!can_add_or_delete(k_old_method)) { return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; } log_trace(redefine, class, normalize) ("Method deleted: old: %s [%d]", k_old_method->name_and_sig_as_C_string(), oi); ++oi; // advance to next old method --- 1026,1041 ---- ("Method added: new: %s [%d]", k_new_method->name_and_sig_as_C_string(), ni); ++ni; // advance to next new method break; case deleted: // method deleted, see if it is OK ! old_flags = (jushort) k_old_method->access_flags().get_flags(); ! if ((old_flags & JVM_ACC_PRIVATE) == 0 ! // hack: private should be treated as final, but alas ! || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 ! ) { ! // deleted methods must be private return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; } log_trace(redefine, class, normalize) ("Method deleted: old: %s [%d]", k_old_method->name_and_sig_as_C_string(), oi); ++oi; // advance to next old method
*** 1170,1179 **** --- 1176,1186 ---- InstanceKlass* scratch_class = SystemDictionary::parse_stream( the_class_sym, the_class_loader, protection_domain, &st, + NULL, // dynamic_nest_host THREAD); // Clear class_being_redefined just to be sure. state->clear_class_being_redefined(); // TODO: if this is retransform, and nothing changed we can skip it
< prev index next >