diff -r ab0121071f54 -r c223b0a9872e hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Mar 10 19:56:19 2015 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Mar 13 12:40:39 2015 -0400 @@ -3492,9 +3492,11 @@ #endif + // RedefineClasses() support for previous versions: - -// Purge previous versions +int InstanceKlass::_previous_version_count = 0; + +// Purge previous versions before adding new previous versions of the class. void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { if (ik->previous_versions() != NULL) { // This klass has previous versions so see what we can cleanup @@ -3524,6 +3526,11 @@ // are executing. Unlink this previous_version. // The previous version InstanceKlass is on the ClassLoaderData deallocate list // so will be deallocated during the next phase of class unloading. + RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is dead", + pv_node)); + // For debugging purposes. + pv_node->set_is_scratch_class(); + pv_node->class_loader_data()->add_to_deallocate_list(pv_node); pv_node = pv_node->previous_versions(); last->link_previous_versions(pv_node); deleted_count++; @@ -3537,7 +3544,7 @@ live_count++; } - // At least one method is live in this previous version so clean its MethodData. + // At least one method is live in this previous version. // Reset dead EMCP methods not to get breakpoints. // All methods are deallocated when all of the methods for this class are no // longer running. @@ -3561,12 +3568,6 @@ ("purge: %s(%s): prev method @%d in version @%d is alive", method->name()->as_C_string(), method->signature()->as_C_string(), j, version)); -#ifdef ASSERT - if (method->method_data() != NULL) { - // Verify MethodData for running methods don't refer to old methods. - method->method_data()->verify_clean_weak_method_links(); - } -#endif // ASSERT } } } @@ -3579,18 +3580,6 @@ ("purge: previous version stats: live=%d, deleted=%d", live_count, deleted_count)); } - -#ifdef ASSERT - // Verify clean MethodData for this class's methods, e.g. they don't refer to - // old methods that are no longer running. - Array* methods = ik->methods(); - int num_methods = methods->length(); - for (int index = 0; index < num_methods; ++index) { - if (methods->at(index)->method_data() != NULL) { - methods->at(index)->method_data()->verify_clean_weak_method_links(); - } - } -#endif // ASSERT } void InstanceKlass::mark_newly_obsolete_methods(Array* old_methods, @@ -3677,6 +3666,11 @@ ConstantPool* cp_ref = scratch_class->constants(); if (!cp_ref->on_stack()) { RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running")); + // For debugging purposes. + scratch_class->set_is_scratch_class(); + scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class()); + // Update count for class unloading. + _previous_version_count--; return; } @@ -3688,8 +3682,8 @@ // if EMCP method (not obsolete) is on the stack, mark as EMCP so that // we can add breakpoints for it. - // We set the method->on_stack bit during safepoints for class redefinition and - // class unloading and use this bit to set the is_running_emcp bit. + // We set the method->on_stack bit during safepoints for class redefinition + // and use this bit to set the is_running_emcp bit. // After the safepoint, the on_stack bit is cleared and the running emcp // method may exit. If so, we would set a breakpoint in a method that // is never reached, but this won't be noticeable to the programmer. @@ -3708,6 +3702,8 @@ assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version"); scratch_class->link_previous_versions(previous_versions()); link_previous_versions(scratch_class()); + // Update count for class unloading. + _previous_version_count++; } // end add_previous_version()