RFR (S): 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop

Vladimir Kozlov vladimir.kozlov at oracle.com
Thu Dec 13 17:11:36 PST 2012


On 12/13/12 4:55 PM, Vladimir Ivanov wrote:
> Vladimir K.,
>
> Thanks for the review!
>
>  > You don't need second region node, use one.
> Can you elaborate on this a little?
> Do you suggest to remove slow_region node? What should I use to point to
> slow path (for example, in generate_slow_guard(bol_thr, slow_call))?

Never mind this. We can't remove slow_region because there are 2 input 
paths.

>
>  > If you rearrange code to generate slow call first and the load on
> fast path last you may not need to preserve init_mem.

It looks like "fast" approach is much more complicated than I thought. 
OK, go with "simple" case but move insert_mem_bar down (below enum) 
where we can see it.

Your comments for enum values are incorrect. !TLS... should be switched 
like next:

      no_int_result_path   = 1, // t == Thread.current() && 
!TLS._osthread._interrupted
      no_clear_result_path = 2, // t == Thread.current() && 
TLS._osthread._interrupted && !clear_int

Thanks,
Vladimir K.

> When considering moving slow path construction up, I was concerned about
> the case where there's no slow path:
>    if (stopped()) {
>      // There is no slow path.
>      result_rgn->init_req(slow_result_path, top());
>      result_val->init_req(slow_result_path, top());
>    } else {
>
> Is it worth retaining?
>
> Best regards,
> Vladimir Ivanov
>
> On 12/14/12 2:05 AM, Vladimir Kozlov wrote:
>> John, the barrier is before enum {} in simple fix.
>>
>> But I also prefer fast code.
>>
>> Vladimir I.,
>>
>> You don't need second region node, use one.
>>
>> If you rearrange code to generate slow call first and the load on fast
>> path last you may not need to preserve init_mem.
>>
>> Thanks,
>> Vladimir K.
>>
>> On 12/13/12 2:31 PM, John Rose wrote:
>>> On Dec 13, 2012, at 3:02 PM, Vladimir Ivanov wrote:
>>>
>>>> http://cr.openjdk.java.net/~vlivanov/8003135/simple/webrev.00
>>>> 31 lines changed: 16 ins; 6 del; 9 mod
>>>>
>>>> In the IR produced by Thread.isInterrupted(Z)Z intrinsic it's
>>>> possible to hoist the load of _interrupted flag out of the loop. The
>>>> fix is to add a barrier to forbid such optimization.
>>>>
>>>> Proposed fix is cleaner that [1] (no explicit memory state management).
>>>> The place for the barrier is deliberately chosen earlier than
>>>> necessary and it blocks hoisting of some loop invariants when
>>>> Thread.isInterrupted() is called in a loop. But I think it's a fair
>>>> price since I don't think that Thread.isInterrupted(Z)Z performance
>>>> in tight loops is critical.
>>>
>>> I don't see any new barrier in the simple fix.  Where is it?  It looks
>>> like the load of thr._interrupted can be hoisted under the same
>>> circumstances as before.  If the slow path is somehow turned into a
>>> loop exit (via uncommon trap, maybe), then the memory state will fold
>>> up and the bit load can be hoisted.
>>>
>>> It seems like your "fast" fix is more robust, for this reason.
>>>
>>> Also, it's not your bug, but I'm not convinced that "slow_val =
>>> intcon(1)" is correct.  I think another thread could come in and clear
>>> the interrupted bit, and this call to the native function could return
>>> false.
>>>
>>>> If you prefer [1] let me know.
>>>>
>>>> Also, cleaned up the code around a little.
>>>
>>> Good cleanups.
>>>
>>> — John
>>>
>>>> Testing: failing test, manual (verified generated code), JPRT (in
>>>> progress)
>>>>
>>>> Thanks!
>>>>
>>>> Best regards,
>>>> Vladimir Ivanov
>>>>
>>>> [1] http://cr.openjdk.java.net/~vlivanov/8003135/fast/webrev.00
>>>


More information about the hotspot-compiler-dev mailing list