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

William Louth (JINSPIRED.COM) william.louth at jinspired.com
Mon Jun 17 07:04:39 EDT 2013


Hi David,

Big things have small beginnings.

I would have to understand more of what this small API change would look 
like before I could determine the impact it would have on all current 
native and non-native agents out in the wild which have been designed 
with the current restrictions (listed in the jep) in mind. What if these 
agents have built up (meta)caches around methods which they now 
incorrectly assume will never be removed? What if the redefinition of a 
superclass invalidates all previous sub classes modifications 
made...this could trigger an avalanche of redefinitions which could 
trigger further redefinitions within one agent or across multiple 
agents. Today there are already issues with the co-existence of multiple 
class transformation agents which we have not worked out in a manner 
that I believe is scalable (in terms of no. of agents).

Well we might very well have to rewrite all agents anyway with the 
module stuff coming ;-).

William

On 17/06/2013 12:42, David Holmes wrote:
> 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.
>
> David
> -----
>   
>> 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