[concurrency-interest] FieldReference vs. AtomicFieldUpdater - was Re: Optimizing Atomic*FieldReference <was> Re: Here's why Atomic*FieldReference access checking is broken

Paul Sandoz paul.sandoz at oracle.com
Thu Oct 9 13:33:23 EDT 2014


On Oct 8, 2014, at 11:19 AM, Peter Levart <peter.levart at gmail.com> wrote:

> Hi Paul,
> 
> Since this thread is way from original topic, I changed it. It is very interesting though.
> 
> On 10/08/2014 06:00 PM, Paul Sandoz wrote:
>> On Oct 8, 2014, at 7:16 AM, Peter Levart <peter.levart at gmail.com> wrote:
>> 
>>> On 10/08/2014 01:19 PM, Doug Lea wrote:
>>>> On 10/08/2014 05:38 AM, Peter Levart wrote:
>>>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/AtomicFieldUpdater.AccessChecks/AnonClassPerCclass/AtomicIntegerFieldUpdater.java 
>>>>> 
>>>> Paul Sandoz has been working on VarHandles (like MethodHandles)
>>>> for similar purposes. Possibly even the same purposes.
>>>> See his JavaOne talk slides at
>>>> http://cr.openjdk.java.net/~psandoz/j1-2014-unsafe-CON5150.pdf
>>>> It seems worth waiting for more progress on this front before
>>>> contemplating changes along these lines.
>>>> 
>>>> -Doug
>>>> 
>>> Thanks Doug for pointing me to Paul's slides. I can see that Paul's VarHandles are based around the idea of methods with polymorphic signature akin to MethodHandles.invoke* with the benefit that they don't declare Throwable as thrown exception and he's adding some type inference changes on top of that.
>>> 
>>> Paul is exploring alternative approaches to JEP 193 which don't require language changes although he has already stepped beyond that line as I can see that his patch contains a few lines of javac changes.
>>> 
>> Yes, it requires some small changes to how polymorphic signature methods are expressed but requires no new language syntax. The downside is the specs require updating to say "here is another class with polymorphic signature methods" so it is not very general.
> 
> And I think you also showed on your slides, that polymorphic signature methods don't provide static type checking. Are there any plans to merge polymorphic signature methods with generic types? Currently both polymorphic signature methods that I know of (MethodHandle.invoke[Exact]) allow passing any type and number of arguments and return Object. Would it be possible to have "constrained" polymorphic signature methods that are static type-checked as normal methods, but otherwise "behave" like polymorphic signature methods?
> 

It's possible:

  http://hg.openjdk.java.net/valhalla/valhalla/jdk/file/bc9fae81d774/src/java.base/share/classes/java/lang/invoke/FieldHandle.java

  http://hg.openjdk.java.net/valhalla/valhalla/jdk/file/bc9fae81d774/src/java.base/share/classes/java/lang/invoke/ArrayHandle.java

(These support a hack that avoids boxing, i referred to in my last email, so explicit int/long versions are not required.)

There is a tension here between what we do for Java 9 and what we can do later on when specialization arrives.

You can find more stuff here:

  http://cr.openjdk.java.net/~psandoz/varhandles/


>> 
>> 
>>> I'm trying to see if there is an alternative to Paul's approach which doesn't require JVM changes either. I think it all boils down to how types involved are encoded and how type-checks can be optimized at runtime. As my preliminary hacking shows, there might be a solution in the existing virtual machinery.
>>> 
>> The key optimization is "final fields are really final" [*], the privilege of which is bestowed on all classes in java.lang.invoke. That enables cast checks to be optimized away under the right conditions. I experimented with Atomic* like classes in that package (plus it is possible to extend the privilege to all classes which of course can be dangerous).
> 
> So if that works, why is FieldReference API designed around polymorphic signature methods then? What do they buy you? Specialization for primitive types? Reification of static types used at call-site?
> 

Essentially one abstract class that covers many access-kinds (static field, instance field, array element, off-heap array, ...) and value-kinds (ref, int, long, ...). The method invocation mechanism is fundamentally the same as that for indy so if we can switch to indy i would expect similar performance characteristics.

Additionally it follows the same approach to lookup as MethodHandles, which I think that is an important pattern access control pattern.


> 
>> 
>> The current VarHandle prototype provides access over fields and array elements (and arrays of primitives off-heap) using just one abstract class. The API is a little raw but when specialization arrives it should be possible to surface a better API without creating specific classes for int/long/ref etc (i managed to hack in an approach in the current prototype to reify type variables while also avoiding boxing, but unfortunately i don't think we can use that technique).
> 
> It may be necessary to have specific classes for int/long/ref because there are operations that you do with int/long that have no meaning with references like addAndGet, etc... but I can see that the number of classes can be reduced this way.
> 

Yes, there could be a concept of a numeric handle exposing addAndGet and such (currently the prototype throws USOE for value-kinds that do not support such operations). This could be surfaced differently using specialization.

>> 
>> There may be ways to surface the same functionality using indy. The trick would be to do this in such a way that javac could use indy or not and there would be no change in semantics, but the JIT could better optimize the former.
>> 
>> Regardless of what way we surface the API there are a few tweaks to the hotspot compiler we can do related to casts and bounds checks (which are mostly important for CAS).
>> 
>> Paul.
>> 
>> [*] This generally seems a very good thing to do if we can work out how to safely support reflection-based seriaization and DI frameworks.
> 
> One way perhaps could be to simply not support it. Static final fields are really final (with exception of System.out/in/err). If instance field is marked as "transient final", reflection could refuse updating it. There are serialization frameworks that (de)serialize even "transient final" fields, so they would fail. But if they are worth anything, they surely must have a mode that works in SecurityManager enabled environments, where updating final fields is not possible so they must be skipped. If backwards compatibility is a must, then a VM switch could turn this feature off. It is, after all, only an optimization.
> 

While it certainly is important for optimization i also consider it important for enforcing the integrity of a class and it's instances (the security manager is a poor mechanism to enforce such integrity). At the moment final does not really mean final (and private does not really mean private).
 

> Otherwise, there would have to be a new language way to mark those fields. What's wrong with @Stable annotation in addition to "transient final" modifiers? It doesn't change the semantics of a program after all. Java serialization would not touch it and reflection could be easily tweaked to refuse updating such fields even if Field.setAccessible(true) was used... It could be useful at least for global JDK-internal use, if it is not fancy enough for general use.
> 

@Stable annotated fields are subtly different, they are really lazy finals as Validmir mentions, something that can be set once from a default to a non-default value (either during the construction phase or anytime outside of that).

My preference at the moment would be to explore how to really make final fields final without any additional qualifications. This connects with how we might improve construction/deserialization and replace usages of Unsafe with safe alternatives using some sort of larval object concept [1].

Paul.

[1] https://blogs.oracle.com/jrose/entry/larval_objects_in_the_vm

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20141009/34e902b5/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 841 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20141009/34e902b5/attachment.bin>


More information about the Concurrency-interest mailing list