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

Volker Simonis volker.simonis at gmail.com
Tue Mar 15 09:46:44 UTC 2016


OK, looks good now.

Regards,
Volker


On Tue, Mar 15, 2016 at 10:25 AM, Nils Eliasson <nils.eliasson at oracle.com>
wrote:

> Hi,
>
>
> On 2016-03-14 16:16, Volker Simonis wrote:
>
>
>
> On Mon, Mar 14, 2016 at 3:43 PM, Nils Eliasson <nils.eliasson at oracle.com>
> wrote:
>
>> Hi Volker,
>>
>> On 2016-03-14 14:58, Volker Simonis wrote:
>>
>> 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:
>>
>>
>> This failure only happened on (slow) non-tiered platforms and the log
>> looked like that as if the compiler even hadn't been put on the compile
>> queue. In the first version of my rewrite I checked the return value from
>> enqueueMethodForCompilation to make sure the compile was actually added.
>> But then I changed my mind and focused on just testing the blocking
>> functionality.
>>
>>  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.
>>
>>
>> Blocking compiles do not get stale any more - that is included in the
>> patch.
>>
>> Only one item will actually be added to the compile queue - the rest will
>> be dropped because the method is already enqueued. The loop makes the code
>> work on all VM-flavours (client, serverm tiered) without worrying about
>> compilation levels. The compilation-lock prevents any compilations from
>> completing - so the all calls on enqueueMethodForCompilation() will be
>> deterministic, and most important - we will get a deterministic result
>> (hanged VM) if the method is blocking here.
>>
>> 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:
>>
>>
>> It can only get on the queue once. It looks like this in the log:
>>
>> Start of test - not blocking
>>
>>     524  257       1       BlockingCompilation::foo (7 bytes)
>>     625  257       1       BlockingCompilation::foo (7 bytes)   made not entrant
>>
>> OK, but then the following loop is useless (and the comment misleading)
> because we actually only enqueue and compile on one level (the first one
> which is available):
>
> I changed to compiling on the highest available comp level.
>
> http://cr.openjdk.java.net/~neliasso/8151796/webrev.07/
>
>
>
>   78         // Normal compile on all levels  79         for (int l : levels) {  80            WB.enqueueMethodForCompilation(m, l);
>   81         }
>
>
> Besides that, your changes look good!
>
> Regards,
> Volker
>
>
> Thank you,
> Nils
>
>
> Directive added, then blocking part where all levels are tested:
>>
>>  1 compiler directives added
>>     626  258    b  1       BlockingCompilation::foo (7 bytes)
>>     627  258       1       BlockingCompilation::foo (7 bytes)   made not entrant
>>     627  259    b  2       BlockingCompilation::foo (7 bytes)
>>     628  259       2       BlockingCompilation::foo (7 bytes)   made not entrant
>>     629  260    b  3       BlockingCompilation::foo (7 bytes)
>>     630  260       3       BlockingCompilation::foo (7 bytes)   made not entrant
>>     630  261    b  4       BlockingCompilation::foo (7 bytes)
>>     632  261       4       BlockingCompilation::foo (7 bytes)   made not entrant
>>
>>
>> And finally the non-blocking part where only one level gets compiled:
>>
>>  633  262       1       BlockingCompilation::foo (7 bytes)
>>
>>
>>  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
>>
>>
>> Thanks for feedback,
>> Nils Eliasson
>>
>>
>>
>> On Mon, Mar 14, 2016 at 12:20 PM, Nils Eliasson <
>> <nils.eliasson at oracle.com>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/20160315/3a613abe/attachment.html>


More information about the hotspot-compiler-dev mailing list