RFR(S):8151796: compiler/whitebox/BlockingCompilation.java fails due to method not compiled

Volker Simonis volker.simonis at gmail.com
Mon Mar 14 13:58:28 UTC 2016


Hi Nils,

thanks for improving the test. I think your fix solves some problems with
regard to fast, non-blocking compiles which are wrongly interpreted as
blocking by the test. But what about the initial test failure:

java.lang.Exception: public static int BlockingCompilation.foo() should be
compiled at level 4(but is actually compiled at level 0)
at BlockingCompilation.main(BlockingCompilation.java:104)

This is from the loop which does blocking compilations. It seems that a
method enqueued for level 4 couldn't be compiled at all. I don't know the
exact reason, but one could be for example that the code cache was full or
that the compiler bailed out because of another reason. I'm not sure we can
accurately handle this situation in the test. Maybe we should tolerate if a
method couldn't be compiled at all:

 121                 if (WB.getMethodCompilationLevel(m) != l* &&
**WB.getMethodCompilationLevel(m) != 0*) {

Also, I don't understand the following code:

  67         // Make sure no compilations can progress, blocking
compiles will hang  68         WB.lockCompilation();
  ...
  78         // Normal compile on all levels  79         for (int l :
levels) {  80            WB.enqueueMethodForCompilation(m, l);
  81         }
  82   83         // restore state  84         WB.unlockCompilation();
 85         while (!WB.isMethodCompiled(m)) {  86
Thread.sleep(100);  87         }  88         WB.deoptimizeMethod(m);
  89         WB.clearMethodState(m);

You enqueue the methods on all levels (let's assume 1,2,3,4). Then you wait
until the method gets compiled at a level (lets say at level 1). I think
this is already shaky, because these are non-blocking compiles of a method
which hasn't been called before, so the requests can be easily get stale.
But lets say the method will be compiled at level one. You then deoptimze
and clear the method state. But the queue can still contain the compilation
requests for the three other levels which can lead to errors in the
following test:

 103                 //Verify that it actuall is uncompiled 104
         if (WB.isMethodCompiled(m)) { 105                     throw
new Exception("Should not be compiled after deoptimization"); 106
           }

Finally some typos:

 103                 //Verify that it actuall*y* is uncompiled

 111                 // Add to queue a*n*d make sure it actually went well


Regards,
Volker


On Mon, Mar 14, 2016 at 12:20 PM, Nils Eliasson <nils.eliasson at oracle.com>
wrote:

> Hi,
>
> Summary:
> The test wasn't as robust as expected.
>
> Solution:
> Change the way we verify that we are having a un-blocking compilation:
> First lock the compilation queue - no new compiles will be completed.
> Enqueue method for compilation. If the method is compiled blockingly - the
> java thread will hang since the compile can't complete as long as the
> compile queue is locked.
>
> Use this to test the blocking functionality in three steps:
> 1) Verify that we are not blocking on target method as described.
> 2) Add compiler directive with instruction to block on target method -
> verify that it can be compiled on all levels. If it is not blocking it will
> eventually be stalled for a moment in the compiler queue and the test will
> fail.
> 3) Pop directive, and redo step one - verify that target method is not
> blocking.
>
> Bug: https://bugs.openjdk.java.net/browse/JDK-8151796
> Webrev:  http://cr.openjdk.java.net/~neliasso/8151796/werev.03/
>
> Regards,
> Nils Eliasson
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20160314/6b7788c7/attachment-0001.html>


More information about the hotspot-compiler-dev mailing list