FTR: JVM Lang Summit presentation
Remi Forax
forax at univ-mlv.fr
Tue Sep 2 18:02:13 UTC 2014
On 09/02/2014 06:59 PM, Paul Sandoz wrote:
> On Aug 8, 2014, at 11:34 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>> Something along :
>>
>> private static MethodHandle compareAndSet(Lookup lookup, Class<?> declaringClass, String fieldName, Class<?> fieldType)
>> throws NoSuchFieldException, IllegalAccessException {
>> MethodHandle getter = lookup.findGetter(declaringClass, fieldName, fieldType);
>> MethodHandleInfo methodHandleInfo = lookup.revealDirect(getter);
>> Field field = methodHandleInfo.reflectAs(Field.class, lookup);
>> long offset = UNSAFE.objectFieldOffset(field);
>> MethodHandle mh = MethodHandles.insertArguments(COMPARE_AND_SWAP_OBJECT, 1, offset);
>> return mh.asType(MethodType.methodType(boolean.class, declaringClass, fieldType, fieldType));
>> }
>>
>> public class VarHandle<T, U> {
>> private final @Stable MethodHandle compareAndSet;
>>
>> VarHandle(MethodHandle compareAndSet) {
>> this.compareAndSet = compareAndSet;
>> }
>>
>> public boolean compareAndSet(T object, U expected, U value) {
>> try {
>> return (boolean)compareAndSet.invoke(object, expected, value);
>> } catch (Throwable e) {
>> if (e instanceof RuntimeException) throw (RuntimeException)e;
>> if (e instanceof Error) throw (Error)e;
>> throw new AssertionError(e);
>> }
>> }
>> }
>>
> (FWIW i initially modified the DHM code to expose out MethodHandles to CAS etc along similar lines to existing DHMs and LFs corresponding to get/putfield.)
>
> Performance-wise, as of now, the above is likely to be slower or on a par with AtomicReferenceFieldUpdater or reflection (if there was a CAS op on Field). Perhaps it will eventually be possible to achieve that with the above, but from what John says it sounds like much investigation is required.
back from vacation too,
slowly trying to anwser to a pile of emails ...
I was to answer yes, but I think the code can be modified a little to
avoid the invoke() and use invokeExact instead
so what about:
private static MethodHandle compareAndSet(Lookup lookup, Class<?> declaringClass, String fieldName, Class<?> fieldType)
throws NoSuchFieldException, IllegalAccessException {
MethodHandle getter = lookup.findGetter(declaringClass, fieldName, fieldType);
MethodHandleInfo methodHandleInfo = lookup.revealDirect(getter);
Field field = methodHandleInfo.reflectAs(Field.class, lookup);
long offset = UNSAFE.objectFieldOffset(field);
MethodHandle mh = MethodHandles.insertArguments(COMPARE_AND_SWAP_OBJECT, 1, offset);
return mh.asType(MethodType.methodType(boolean.class, declaringClass, fieldType, fieldType))
asType(MethodType.methodType(boolea,.class, Object.class, Object.class, Object.class));
}
public class VarHandle<T, U> {
private final @Stable MethodHandle compareAndSet;
VarHandle(MethodHandle compareAndSet) {
this.compareAndSet = compareAndSet;
}
public boolean compareAndSet(T object, U expected, U value) {
try {
return (boolean)compareAndSet.invokeExact(object, expected, value);
} catch (Throwable e) {
if (e instanceof RuntimeException) throw (RuntimeException)e;
if (e instanceof Error) throw (Error)e;
throw new AssertionError(e);
}
}
}
if the VarHandle is stored in a static final, the JIT should be able to
remove the downcast/upcast pair.
>
> Any replacement of Unsafe in j.u.concurrent classes has to be almost, if not, as performant as that of direct Unsafe usage. It's proving quite useful to have something that works along similar fundamental lines (w.r.t. method invocation) that already gets quite close to Unsafe performance and from which we can evaluate and improve certain aspects.
Anyway, i still think that the best way to write a safe compareAndSet is
not to use a Varandle or any polymorphic signature method, but to let
the compiler generate an invokedynamic with the right signature. The
bootstrap method will verify the signature once (at link time) and so
the generated method handle will only do downcasts to j.l.Object,
something that the JIT will trivially consider as a no-op.
>
> Paul.
Rémi
More information about the valhalla-dev
mailing list