[concurrency-interest] Does factoring out VarHandle-based manipulations cause performance penalties?

Aleksey Shipilev shade at redhat.com
Wed Aug 9 04:25:04 EDT 2017


On 08/09/2017 10:17 AM, Dávid Karnok wrote:
> In my codebase, targeting Java 9, I often have to perform the same set of atomic operations on
> fields of various classes, for example, a deferred cancellation of Flow.Subscriptions:
> 
> Flow.Subscription upstream;
> static final VarHandle UPSTREAM;
> 
> @Override
> public void cancel() {
>     Flow.Subscription a = (Flow.Subscription)UPSTREAM.getAcquire(this);
>     if (a != CancelledSubscription.INSTANCE) {
>         a = (Flow.Subscription)UPSTREAM.getAndSet(this, CancelledSubscription.INSTANCE);
>         if (a != null && a != CancelledSubscription.INSTANCE) {
>             a.cancel();
>         }
>     }
> }
> 
> Refactored into:
> 
> final class SubscriptionHelper {
> 
>     public static void cancel(Object target, VarHandle handle) {
>         Flow.Subscription a = (Flow.Subscription)handle.getAcquire(target);
>         if (a != CancelledSubscription.INSTANCE) {
>             a = (Flow.Subscription)handle.getAndSet(target, CancelledSubscription.INSTANCE);
>             if (a != null && a != CancelledSubscription.INSTANCE) {
>                 a.cancel();
>             }
>         }
>     }
> }
> 
> @Override
> public void cancel() {
>     SubscriptionHelper.cancel(this, UPSTREAM);
> }
> 
> 
> I'd think JIT can and will inline SubscriptionHelper.cancel to all its use sites, but the fact that
> the cancel method no longer has "this" but an arbitrary target Object, my concern is that the
> optimizations may not happen.
> 
> I haven't noticed any performance penalties so far but I remember Aleksey Shipilev mentioning
> somewhere, some time ago, a warning about such out-of-context VarHandle uses.

Like with Unsafe, like with Atomic*FieldUpdaters, like with *Handles in general, the compiler's
ability to optimize is dependent on constant propagation. Putting the VarHandle to static final
field helps that a lot, with the same mechanism as putting OFFSET for Unsafe accesses helps
performance.

It your case above, making VarHandle a method parameter is performance-risky move, but it is
mitigated by the use-site that loads it from the static final field anyway. Thus, if method is
inlined, you get the same benefits. The concern for "Object" and "this" is not valid there, I think,
because inlining propagates type information too.

Thanks,
-Aleksey


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20170809/60176085/attachment.sig>


More information about the Concurrency-interest mailing list