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

Peter Levart peter.levart at gmail.com
Mon Jun 17 11:39:44 EDT 2013


On 06/17/2013 12:42 PM, Oleksandr Otenko wrote:
> Change the return type of the methods returning field offsets from int 
> to FieldOffset. Now all references to FieldOffsets are accounted for.

Perhaps the Unsafe API could be gradually replaced with some other more 
manageable API that would be "Safe", in addition to provide for class 
redefinition.

The MethodHandle API is safe and at least for constant direct method 
handles it has been proven that it can be JIT-ed to fast in-lined code. 
Suppose that in addition to:

Lookup.findGetter/findSetter

There would also be:

Lookup.findVolatileGetter/findVolatileSetter/findOrderedSetter
Lookup.findCompareAndSwap/findGetAndSet/findGetAndAdd

+ the support for array access.

Now that there is Unsafe.[load|store|full]Fence, the 
Unsafe.[put|get][Volatile|Ordered] or equivalents are not needed any 
more and only the replacements for CAS/GAS/GAA are needed.

Regards, Peter

>
> Alex
>
> On 04/06/2013 21:19, Nathan Reynolds wrote:
>> 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
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20130617/5dccb8bb/attachment.html>


More information about the Concurrency-interest mailing list