RFR(M/L): 7115356: assert(!m->was_never_executed()) failed
Nils Eliasson
nils.eliasson at oracle.com
Thu Sep 18 12:47:58 UTC 2014
I think Vladimir is right with his observation that JDK-8058564 is the
actual cause.
The scenario I see is that the carry may be observed as 0 immediately
after setting it (by the same thread).
Thread A running: InvocationCounter::set_carry()
Thread B running: InvocationCounter::set(State state)
A reads _counter with carry 0
B writes carry 1
A writes _counter with carry 0
B reads _counter to mask out carry, finds carry is 0
B writes _counter with carry 0
Result: _counter ends up with the count from B but carry from A.
- In my refactored version this turns into:
A reads _counter, carry 0
B reads _counter, carry 0
A writes counter with carry 0 / B writes counter with carry 1
We still might end up with loosing any update - but they will at least
be internally consistent - if the flag is set - the count was reduced,
and if it was not - the count is still high. However this scenario
doesn't explain how the count gets to zero.
//Nils
On 2014-09-18 04:45, Vladimir Kozlov wrote:
> The clean up is nice.
> As David I want to see the cause description. I tried to find a cause
> together with Rickard without much success.
>
> The assert we hit is next after 2 set_carry() calls:
>
> mcs->invocation_counter()->set_carry();
> mcs->backedge_counter()->set_carry();
> assert(!m->was_never_executed(), "don't reset to 0 -- could be
> mistaken for never-executed");
>
> where
>
> bool was_never_executed() { return !was_executed_more_than(0); }
>
> The only code which can return 'false' from was_executed_more_than(0)
> is next:
>
> return invocation_count() > 0;
>
> Failures happens without tiered compilation an on Windows only (?).
> In such case invocation_count() returns:
>
> return (mcs == NULL) ? 0 : mcs->invocation_counter()->count();
>
> You would assume that mcs != NULL because we just accessed it before
> the assert.
>
> The one explanation is race during MethodCounters creation which Igor
> is fixing (8058564). Which can produce 0 count.
>
> Vladimir
>
> On 9/17/14 7:05 AM, Nils Eliasson wrote:
>> Hi,
>>
>> Please review this change. It started out as a bug fix and grew with
>> some refactoring of invocationCounter.cpp/hpp and its uses.
>>
>> The original problem was that an assert in compilationPolicy failed
>> because a value that was just set could not be observed. Some code paths
>> read the composite counters a part at a time and may observe and write
>> inconsistent values when several threads are using them. While removing
>> a few unnecessary read and writes of the 'state' field, I noticed the
>> state and Action was actually never used. I removed it all and came up
>> with much simpler code.
>>
>> Major refactorizations:
>> 1) Rewritten invocationCounter methods to read entire counter,
>> manipulate and then write entire counter.
>> 2) Removed the state, and action - it was never used anywhere.
>> 3) Moved invocation counter logic from simpleThresholdPolicy into
>> invocationCounter.
>>
>> bug: https://bugs.openjdk.java.net/browse/JDK-7115356
>> webrev: http://cr.openjdk.java.net/~neliasso/7115356/webrev.06
>>
>> This code might affect the logCompilation and replay tools since it
>> changes the output. I will test and fix that before submitting. I will
>> also do some performance testing to make sure I haven't messed up the
>> counters in any way.
>>
>> Thanks,
>> Nils Eliasson
More information about the hotspot-compiler-dev
mailing list