Implementing VarHandle

Remi Forax forax at univ-mlv.fr
Wed Apr 15 16:21:12 UTC 2015


On 04/15/2015 04:04 PM, Paul Sandoz wrote:
> On Apr 15, 2015, at 3:06 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>
>> On 04/15/2015 02:24 PM, Paul Sandoz wrote:
>>> Hi Remi,
>>>
>>> I am always impressed by the ability of MHs, and your ability to use them :-)
>>>
>>> With the API you have defined in the VarHandle2 class located in j.l.invoke i strongly suspect you do not need to use method handles. The public methods could directly use casts/null-checks and Unsafe.
>> yes,
>> I use method handles here mostly to avoid to write all combinations by hands,
>> that said, I still need to cut & paste the invocation code (the one that call invokeExact).
>>
>>> Roland and Vladimir (K.) fixed issues with "null-check droppings" by making Class.cast an intrinsic (which iIIRC gave some benchmarks a little perf boost), so if the class is constant the cast should just fold away without leaving any trace.
>> yes, it's funny that because instanceof and a checkcast behave differently for null, you need two different intrinsics.
> Right.
>
>
>> I'm glad there is already a patch to make Class.cast an intrinsic, I was about raising that very same question.
>> I suppose that once this patch will be integrated,
> It should already in jdk9/dev/hotspot.
>
>    https://bugs.openjdk.java.net/browse/JDK-8054492
>
>
>> MethodHandle.asType impleemntation will be retrofitted to use Class.cast.
>>
> Yes, it should be possible to replace/update MethodHandleImpl.castReference:
>
> @ForceInline
> @SuppressWarnings("unchecked")
> static <T,U> T castReference(Class<? extends T> t, U x) {
>      // inlined Class.cast because we can't ForceInline it
>      if (x != null && !t.isInstance(x))
>          throw newClassCastException(t, x);
>      return (T) x;
> }
>
> I logged an issue a while ago.
>
>    https://bugs.openjdk.java.net/browse/JDK-8062543

Fixing this will make all dynamic languages a little faster, or at least 
generate more readable assembly code :)

>
>
>
>>> It's statically type safe for the receiver but not for the value, a compromise to reduce the number of handle classes. Ideally what you want is VarHandle2<T, V>, but until valhalla arrives V is problematic.
>> even with primitive specialization of generics, you still have the issue that getAndAdd and addAndGet mean nothing on a V which is a reference. So you need a way to restrict V to only primitives for these two methods.
> Yes. I was pondering a hierarchy with BasicFieldHandle, FieldHandle and NumericFieldHandle etc. It felt like things were getting a little out of control for 9.

As you said, if the implementation of the field updater is in 
java.lang.invoke,
we can fix the performance issue of the current implementation.
So it can be enough for 9, apart from the off-heap use case.


>
>
>>>   I tried push this as far as i could with a FieldHandle<T, V> where, say, "Integer" really meant "int", but ultimately it was an awkward fit and there was a risk it would not be right when valhalla is ready so we decided not to pursue that direction.
>>>
>>>
>>> A VarHandle (as currently designed) is a cross product of variable location, variable type and access mode.
>>>
>>> The single class can support variable locations that are instance fields, static fields, array elements, and even off-heap array elements (perhaps indexed by long rather than int, and/or hooked up to direct byte buffers). For the former two, access modes work independently of whether the field is volatile or not (access is not possible if a field is final). I also want to support relaxed and volatile access for all primitive types (so the scope of supported variable types is the same as that for DHMs to fields).
>> I wonder if all platform supported by OpenJDK are able to do a CAS on a byte ?
> I was referring just to relaxed and volatile set/get access (like that for DHMs to fields), enhanced atomic access modes would throw a USO, one could support other fenced access modes with explicit fences (which may result in strong than necessary requirements) but not sure it is worth it.

yes, not sure there is a real use case.

>
>
>> I still fail to see the point to mix support for array based method and field based method through one public API.
>>
> Just reduces the surface area to something minimal yet powerful enough for Unsafe use cases (like that in j.u.c). We should be able to something better for more general developers after 9 when valhalla solidifies.

yes, see my answer above.

>
>
>>> I tried to design the implementation so there are minimal dependencies (as you point out in a later email CHM is problematic) and so that a minimal amount of work is performed by the runtime compiler, when say inlining accesses in complex j.u.c code. (It's feasible the implementation could use LambdaForms, or could change as possible advances are made to hotspot and the invoke classes.)
>>>
>>> It's definitely not designed for every day developer use (as i think is also the case for MHs). It's focus is advanced developers currently using Unsafe.
>>>
>>> You can find some "live" patches against hs-rt here:
>>>
>>>    http://cr.openjdk.java.net/~psandoz/jdk9/varhandles/
>> My main issue with the current design is the use of the polymorphic signature, which mean that you loose the ability to have a clean doc that describes what the methods do, you don't even have the number of parameters.
> Yes, it's "MethodHandles for data".

No it's not, mostly because you have an infinite number of methods with 
any possible semantics and you have a finite number of field accessors 
with a very precise semantics, because of that using the polymorphic 
signature vehicle for implementing these accessors feels wrong too me.

>
> Paul.

Rémi



More information about the valhalla-dev mailing list