Broken thread scheduling in indexed loop (missing safepoint?)

Vitaly Davidovich vitalyd at gmail.com
Fri Nov 30 15:48:39 PST 2012


PhaseIdealLoop::is_counted_loop() answered my 2nd question - it doesn't
seem to need compile time constant.  Among other conditions, it has to be
loop invariant but not constant.  That method is a monster btw :)

Sent from my phone
On Nov 30, 2012 6:37 PM, "Vitaly Davidovich" <vitalyd at gmail.com> wrote:

> What's the reason safepoints were yanked out in the first place? I'd
> assume safepoints aren't that frequent, at least while a typical loop is
> running.  Once the polling page is in cache (first iteration will bring it
> in) and assuming the test instruction on it will always go the same way
> (i.e. safepoint not requested) won't the cache hitting load and perfectly
> predicted (common case) branch not have noticeable impact on the loop? Or
> am I underestimating safepoint frequency? Or is the polling test in the
> loop inhibiting some optimizations due to control flow? Or something else?
> :)
>
> Also, counted loops are only those with a compile time constant limit,
> right? Or does a read of a final field (or otherwise deduced by JIT to be a
> runtime constant) whose value is the loop limit also count?
>
> Thanks
>
> Sent from my phone
> On Nov 30, 2012 6:19 PM, "Vladimir Kozlov" <Vladimir.Kozlov at oracle.com>
> wrote:
>
>> On 11/30/12 12:51, Vitaly Davidovich wrote:
>>
>>> By the way, what would a fix involve? Polling for safepoint every X
>>> trips through the loop where X is some reasonable value and then
>>> overridable via a JVM arg? I guess otherwise the JVM would have to
>>> know/estimate the cost of the loop body, which seems intractable in
>>> general.
>>>
>>
>> An other approach is "mine stripping" - split a loop into inner and outer
>> loops.
>> Polling not on each iteration requires test and branch which could be
>> more expensive than load with unused result.
>> Current plan (6869327) is simple to keep safepoint in counted loop when
>> the flag is specified.
>>
>> Vladimir
>>
>>
>>> What does J9 do? Does it simply not strip out polling?
>>>
>>> Thanks
>>>
>>> Sent from my phone
>>>
>>> On Nov 30, 2012 3:28 PM, "Volker Simonis" <volker.simonis at gmail.com
>>> <mailto:volker.simonis at gmail.**com <volker.simonis at gmail.com>>> wrote:
>>>
>>>     Hi Vitaly,
>>>
>>>     you're right, even a STW GC will have to wait until this loop
>>>     without a safepoint will finish. On the other side, if there is an
>>>     allocation inside the loop, the allocation will be done on the "fast
>>>     path" (without safepoint check) only until the thread local buffer
>>>     (TLAB) will be full. After that it will have to take the "slow path"
>>>     which is a VM call and which has a safe point check. So in practice
>>>     I think the problem is only with very tight loops which do same
>>>     small but expensive computations (or with nested int loops which
>>>     have potentially the same complexity like long loops but no safpoint
>>>     either).
>>>
>>>     Regards,
>>>     Volker
>>>
>>>     On Friday, November 30, 2012, Vitaly Davidovich wrote:
>>>
>>>         Hi Volker,
>>>
>>>         Just curious - what happens if a STW GC needs to occur right as
>>>         this type of loop is entered? Does the VM just stall until the
>>>         loop exits? What if this loop does a fast path allocation on
>>>         some iteration? Do all allocations check for safepoints
>>> internally?
>>>
>>>         Thanks
>>>
>>>         Sent from my phone
>>>
>>>         On Nov 30, 2012 1:41 PM, "Volker Simonis"
>>>         <volker.simonis at gmail.com> wrote:
>>>
>>>             Hi,
>>>
>>>             This is a long standing problem of HotSpot (compared for
>>>             example to
>>>             J9). It doesn't put Safepoints into counted int loops
>>>             (because it
>>>             assumes they will terminate just "fast enough" which is not
>>>             the case
>>>             in your example). You can see another example for this
>>>             behavior in
>>>             these slides
>>>             "http://www.progdoc.de/papers/**Jax2012/jax2012.html#%288%29<http://www.progdoc.de/papers/Jax2012/jax2012.html#%288%29>
>>> "
>>>             together with the generated assembler code.
>>>
>>>             You can easily solve the problem by making your loop
>>>             variable a "long"
>>>             instead of an "int". In that case, HotSpot will be more
>>>             cautious and
>>>             place a safepoint into the loop.
>>>
>>>             Regards,
>>>             Volker
>>>
>>>             On Fri, Nov 30, 2012 at 2:05 PM, Alexey Goncharuk
>>>             <agoncharuk at gridgain.com> wrote:
>>>              > Hi,
>>>              >
>>>              > We faced some weird issue with thread scheduling. At a
>>>             first glance it
>>>              > looked like it relates to
>>>              >
>>>             http://bugs.sun.com/**bugdatabase/view_bug.do?bug_**
>>> id=7160161 <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7160161>
>>>             but not exactly.
>>>              >
>>>              > This is the code we ran:
>>>              >
>>>              > public static void main(String[] args) throws Exception {
>>>             Thread worker =
>>>              > new Thread() { @Override public void run() { double d =
>>>             0; for (int j = 1; j
>>>              > < 2000000000; j++) d += Math.log(Math.E * j);
>>>             System.out.println(d); } };
>>>              > Thread reporter = new Thread() { @Override public void
>>>             run() { try { while
>>>              > (true) { Thread.sleep(1000); System.out.println("Running:
>>> " +
>>>              > System.currentTimeMillis()); } } catch
>>>             (InterruptedException ignored) {
>>>              > Thread.currentThread().**interrupt(); } } };
>>>             reporter.start(); worker.start();
>>>              > worker.join(); reporter.interrupt(); }
>>>              >
>>>              > One can expect that printing thread would output messages
>>>             during all the
>>>              > calculation time, however it hangs after 3-4 iterations.
>>>             Setting
>>>              > -XX:FreqInlineSize=0 as described in original bug report
>>>             does not help in
>>>              > this case, but if I extract loop body into a separate
>>>             method, setting this
>>>              > option works. Example passes with -Xint option as well.
>>>             (Tested with
>>>              > 1.6.0_33, 1.6.0_37, 1.7.0_07 on Windows and 1.6.0_33 on
>>>             Linux)
>>>              >
>>>              > I saw #7160161 marked as resolved, so I just wanted to
>>>             confirm if behavior
>>>              > we see really relates to this issue and it was fixed (bug
>>>             report covers
>>>              > non-Counted loop only).
>>>              >
>>>              > Also, is there any other workarounds rather then
>>>             extracting the method and
>>>              > specifying FreqInlineSize=0?
>>>              >
>>>              > Thanks,
>>>              > Alexey Goncharuk
>>>              >
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20121130/ec64a591/attachment.html 


More information about the hotspot-compiler-dev mailing list