JDK-8055008 : Clean up code that saves the previous versions of redefined classes
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-08-13
  • Updated: 2021-11-16
  • Resolved: 2014-09-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9 Other
8u162Fixed 9 b32Fixed emb-8u181Fixed
Related Reports
Relates :  
Description
For class redefinition, the old methods point to the old constant pool which points to the original class.   The scratch class created during redefinition points to the old methods and old constant pool, and the original class points to the new (merged) constant pool and new methods.  The pointers are such after class redefinition:

original_class->new_cpool->original_class
original_class->new_methods->new_cpool->original_class (this is good!)

scratch_class->old_cpool->original_class
scratch_class->old_methods->old_cpool->original_class (this is inconsistent but necessary [1])

[1] there's a giant comment why this is necessary in jvmtiRedefineClasses.   This is actually something we want to change, so different RFE later.

If any of the old_methods are still running when we redefine the classes, we mark them "on_stack" during class unloading so that we don't deallocate the metadata for them.   When we mark them on_stack we also mark the old_cpool on_stack because the old methods need the old_cpool.   During class redefinition, we put the scratch_class on the deallocation list, but we don't actually deallocate it until all of the old methods are no longer running.

InstanceKlass::on_stack() { return constants->on_stack(); }

The reason for this is because InstanceKlass is a reliable hook for deallocating metadata in the no-permgen world.   With PermGen, I believe scratch_class would have been collected before the old methods so we needed to save running old EMCP methods on the PreviousVersionNode (list) as weak references to hold pointers to them.   The pointers to the old_methods are held mainly so that we can set breakpoints in EMCP methods - methods that are equivalent except they point to a merged constant pool (but they don't).   If someone sets a breakpoint in a new method and there's an equivalent method before redefinition still running, they expect a breakpoint in the equivalent method.

With no-Permgen, we should use scratch_class to link to the previous versions to hold the old_methods which will make this simpler, more explicit, and remove the PreviousVersionNode structure(s).
Comments
URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/e3fb51ae8d7d User: lana Date: 2014-09-24 20:47:23 +0000
24-09-2014

URL: http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/rev/e3fb51ae8d7d User: coleenp Date: 2014-09-04 00:16:37 +0000
04-09-2014

This should move from hotspot/runtime -> hotspot/jvmti for proper visibility.
13-08-2014