[concurrency-interest] lazy finals - was: Here's why Atomic*FieldReference access checking is broken

Vitaly Davidovich vitalyd at gmail.com
Fri Oct 10 11:09:17 EDT 2014


Thanks Vladimir for expanding.

For the latter case, after the class (which violates CHA dependency) is
> loaded, VM guarantees there are no and won't be any running activations of
> affected nmethods in the system. To achieve that VM supports forcible
> deoptimization (and guards are an example of cooperative deoptimization) -
> it patches all affected activations forcing execution to continue in the
> interpreter.


Just to confirm, the VM loads the class and sees a dependency was
registered for CHA purposes that the newly loaded class violates.  The
ensuing patching is done under a safepoint, right?

As an aside, classes marked final do not register any loader dependencies
right? (i.e. the JIT respects final on the class, even if none of the
non-private methods are marked final).  This is what I'd expect, but just
want to double-check.

IMO, finals are closer to latter case, so once a field is changed, there
> should be no nmethods embedding stale value running in the system. The
> strategy should adapts to the application, so if an application repeatedly
> changes a final field and invalidates some methods, VM should leave the
> loads from that field as is. Current deoptimization machinery supports such
> scenario.


Makes sense, agree.

But it's just a way to optimize existing scenario. I agree with Pal that
> safe mechanism for the DI and serialization would be much better.


Also agree :).  It's a shame that optimizations for final fields needs to
jump through hoops because of DI/serialization.

On Fri, Oct 10, 2014 at 10:48 AM, Vladimir Ivanov <
vladimir.x.ivanov at oracle.com> wrote:

> Guards and nmethod dependencies are complementary mechanisms to track
> actual dependencies of the generated code. What matters is how frequent
> "uncommon" is: "never" (0 out of 1M), "seldom" (10s out of 1M), "rare"
> (1000s out of 1M). Guards are always executed, so it's a good fit for
> checks for relatively rare conditions, but if condition is never met, it
> may be too much work. On the other hand, dependencies has zero overhead for
> common case, but deoptimization is prohibitively expensive - requires the
> whole VM to reach safepoint and invalidates all nmethod activations.
>
> Depending on the property a dependency tracks, nmethod invalidation can be
> delayed or even never happen.
>
> Consider 2 cases: class redefinition and CHA property invalidation.
>
> In the former case, it's fine to have activations of stale versions in the
> system (spec allows that), but new invocations should target latest
> version. There's no need to invalidate existing activations.
>
> For the latter case, after the class (which violates CHA dependency) is
> loaded, VM guarantees there are no and won't be any running activations of
> affected nmethods in the system. To achieve that VM supports forcible
> deoptimization (and guards are an example of cooperative deoptimization) -
> it patches all affected activations forcing execution to continue in the
> interpreter.
>
> IMO, finals are closer to latter case, so once a field is changed, there
> should be no nmethods embedding stale value running in the system. The
> strategy should adapts to the application, so if an application repeatedly
> changes a final field and invalidates some methods, VM should leave the
> loads from that field as is. Current deoptimization machinery supports such
> scenario.
>
> But it's just a way to optimize existing scenario. I agree with Pal that
> safe mechanism for the DI and serialization would be much better.
>
> Best regards,
> Vladimir Ivanov
>
> On 10/10/14, 1:30 AM, Vitaly Davidovich wrote:
>
>>     How does Hotspot deal in general with situations where the optimized
>>     code, while executing, invalidates it's assumptions? Does this ever
>>     happen currently?
>>
>>
>> I think this depends on the type of assumptions/optimizations made.  In
>> some cases, a "guard" is installed, which if it doesn't pass, triggers
>> deoptimization (i.e. generated code does some cheap check, and if it
>> doesn't pass, calls a runtime function that triggers deopt).  Other
>> cases piggyback on things like class loading (e.g. devirtualizing
>> because only one known type is loaded), and register class loading
>> dependencies that, if triggered, will trigger deoptimization.
>>
>> I suspect Vladimir's proposal will require another type of hook that
>> triggers when a final field is modified (so similar in principle to
>> class loading hooks).
>>
>> On Thu, Oct 9, 2014 at 4:53 PM, Peter Levart <peter.levart at gmail.com
>> <mailto:peter.levart at gmail.com>> wrote:
>>
>>
>>     On 10/09/2014 07:53 PM, Paul Sandoz wrote:
>>
>>>     On Oct 9, 2014, at 3:23 AM, Vladimir Ivanov<vladimir.x.ivanov@
>>> oracle.com>  <mailto:vladimir.x.ivanov at oracle.com>  wrote:
>>>
>>>>     What HotSpot misses right now (to preserve correctness w.r.t.
>>>> Reflection API) is a way to track dependencies between final fields and
>>>> nmethods which embed their values. It would allow to invalidate all
>>>> nmethods which rely on stale value and ensure the updated value is
>>>> "visible" everywhere in the running application.
>>>>
>>>>      In such a case would it provide a form of eventual consistency or
>>> would there be checks in place before a final field is used? e.g. one
>>> thread could be stomping on a final field while another thread is executing
>>> an nmethod under the assumption the field is final (and what if the nmethod
>>> is executing a large or infinite loop?).
>>>
>>
>>     Or, if nmethod that depends on the value of the field which is
>>     constant-folded in it's code, modifies this same field in 1st part
>>     and after that executes 2nd part that uses constant-folded value?
>>     How does Hotspot deal in general with situations where the optimized
>>     code, while executing, invalidates it's assumptions? Does this ever
>>     happen currently?
>>
>>     Regards, Peter
>>
>>      Instead perhaps final fields should really be final and safe
>>> mechanisms are provided to support the DI and serialization use-cases,
>>> which i suspect cover almost all use-cases.
>>>
>>>     Paul.
>>>
>>>
>>>     _______________________________________________
>>>     Concurrency-interest mailing list
>>>     Concurrency-interest at cs.oswego.edu  <mailto:Concurrency-interest@
>>> cs.oswego.edu>
>>>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>
>>
>>
>>     _______________________________________________
>>     Concurrency-interest mailing list
>>     Concurrency-interest at cs.oswego.edu
>>     <mailto: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/20141010/baf56783/attachment.html>


More information about the Concurrency-interest mailing list