[concurrency-interest] JEP-159 Enhanced Class Redefinition vs Unsafe.___FieldOffset()

David Holmes davidcholmes at aapt.net.au
Mon Jun 17 06:42:10 EDT 2013

william.louth at jinspired.com writes:
> The "small impact" mention in the proposal seems like an 
> understatement to say the least.

To be fair it says: "There is a small impact on the API documentation for the class redefinition functionality in JVMTI, JDWP, JDI, and the java.lang.instrument API."

Personally I think that field removal should only be possible if it can be shown that the redefined methods never access the field - an enhanced form of verification. Otherwise you are going to have to add numerous checks to the VM to handle the possibility of suddenly vanishing fields. I can't imagine such checks being favourable to performance.

> With regard to field addition might I suggest that instead we 
> look at the introduction of "twinned" class instances such that 
> for any instance of class A I can obtain (with ease and speed) a 
> "twinned" instance of class B (struct) which would hold the 
> fields I would like added. An added benefit of this is that the 
> twinned class would not need to be exposed (inadvertently) to 
> other code access class A. Doing this without support within the 
> JVM today results in far too much memory management work and 
> relatively expensive hash lookups. I have not given my proposal 
> much thought until this morning so apologies if I have over 
> simplified the problem itself.
> William
> >-----Original Message-----
> >From: Nathan Reynolds [mailto:nathan.reynolds at oracle.com]
> >Sent: Tuesday, June 4, 2013 10:19 PM
> >To: concurrency-interest at cs.oswego.edu
> >Subject: [concurrency-interest] JEP-159 Enhanced Class 
> Redefinition vs	Unsafe.___FieldOffset()
> >
> >JEP 159 Enhanced Class Redefinition 
> >(seehttp://openjdk.java.net/jeps/159) will allow for adding and removing 
> >fields in a class.  Also, a field could be changed in size as well (e.g. 
> >long → int).  When the change happens, the heap is scanned for all of 
> >the instances of the class(es) and all of the instances are modified.  
> >The cost is about that of a full GC.
> >
> >I think the original driver for JEP 159 was to enhance what debuggers 
> >can change on the fly as the program is running.  I envision using JEP 
> >159 to remove dead fields, deal with fields used in a small percentage 
> >of instances (rarely used) and reduce the size of oversized fields.  
> >Dead and rarely used fields account for 6.9% of an average heap.  
> >Oversized fields account for 1.5% of an average heap.  By _occasionally_ 
> >using JEP 159 at runtime, we could change the class definitions to save 
> >most of this space and hence improve GC times and perhaps response times.
> >
> >If I understand correctly, Unsafe.objectFieldOffset() and 
> >Unsafe.staticFieldOffset() return the number bytes from the beginning of 
> >the instance or class where the field is located.  This offset is 
> >typically obtained when the class is loaded or the instance is 
> >constructed.  For example, 
> >java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater will get 
> >the offset in the constructor for the specified field and class.  It 
> >keeps this offset for the lifetime of the CASUpdater instance.  The 
> >field and class can be any loaded class.
> >
> >So, what will happen when JEP 159...
> >
> > 1. removes the field used by CASUpdater?  It seems like CASUpdater will
> >    corrupt the instance or the object header of the next object.
> > 2. adds or removes a different field and this shifts the field used by
> >    CASUpdater?
> > 3. changes the long field to an int?
> > 4. adds or removes @Contended?  This will rearrange the fields in all
> >    of the instances.
> >
> >CASUpdater is just one class.  What about all of the other classes which 
> >use or _will_ use Unsafe.___FieldOffset?
> >
> >Maybe JEP 159 has already solved the problem.  If so, I would like to 
> >hear how.  If not, how can this problem be solved?
> >
> >If JEP 159 changes the returned value of ___FieldOffset() from an offset 
> >to a cookie, what code will break which assumes it is an offset?
> >
> >The value returned from Unsafe.___FieldOffset seems to be used as a 
> >cookie.  This cookie can be an index into an array of field offsets.  
> >JEP 159 will then have to fix up the array of field offsets for the 
> >affected classes.  If a field is removed or altered in size, then the 
> >existing entry in the array should be changed to an error flag (i.e. 
> >-1).  In the case of adding or altering a field, then a new entry should 
> >be added to the array.  This will prevent corruptions since the Unsafe 
> >operations will check the entry for the error flag.
> >
> >The engineer will have to be aware that if they change the size of the 
> >field from a long to an int, then they have to change the 
> >AtomicLongFieldUpdater to an AtomicIntegerFieldUpdater.  Currently, the 
> >compiler doesn't flag a problem if an Atomic__FieldUpdater specifies a 
> >non-existent field or a field of the wrong type or non-volatile.  These 
> >checks are left for runtime.  Maybe the compiler should make this check 
> >as well.
> >
> >The code that deals with dead, rarely used and oversized fields can't 
> >change the fields that were used by Unsafe.___FieldOffsets. If a field 
> >is changed and then Unsafe.___FieldOffset is called on that field, then 
> >those fields will have to be reverted.
> >
> >Is there a better solution?
> >-- 
> >Nathan Reynolds 
> ><http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> | 
> >Architect | 602.333.9091
> >Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology
> >
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 2013.0.3345 / Virus Database: 3199/6417 - Release Date: 06/16/13

More information about the Concurrency-interest mailing list