RFR(S): G1: assert(_finger == _heap_end) failed, concurrentMark.cpp:809

Bengt Rutisson bengt.rutisson at oracle.com
Wed Mar 13 06:05:44 PDT 2013


Hi John,

Thanks for splitting this up into two webrevs! :)

I understand that we only have to reset the marking phase in 
enter_first_sync_barrier() if we are during concurrent mark since we are 
anyway doing it in checkpointRootsFinal(). And I think you are correct 
about the fact that we don't have to drain the discovered references if 
we have hit an overflow.

So, basically I think I understand the changes for 1. and 3. that you 
explained below.

I'm struggling a bit to grasp the change motivated by 2. Are these the 
calls to set_phase() that triggered the assert before? Do we still need 
to remove them considering that we no longer reset the marking phase 
during remark?

Also, you replaced the calls to set_phase() with calls to 
_cm->terminator()->reset_for_reuse(_active_workers). The comment says 
that this is necessary for the termination protocol in do_marking_step() 
to work properly. But that method also uses _first_overflow_barrier_sync 
and _second_overflow_barrier_sync. Don't we have to reset those too? 
Similarly to what set_phase() does?

Finally, why does it say "// Not strictly necessary but..." in 
G1CMRefProcTaskExecutor::execute() ?

Sorry for all the questions, but I'm really not that familiar with this 
code.

Bengt


On 3/13/13 1:10 AM, John Cuthbertson wrote:
> Hi Everyone,
>
> Can I have a couple of volunteers look over these changes? The webrev 
> can be found at: http://cr.openjdk.java.net/~johnc/8009940/webrev.0/
>
> These changes were, at Bengt's request, split out from the original 
> webrev for 8009536. In the webrev they have been applied on top of 
> 8009536 but they are independent. The issue has been in the G1 code 
> for a while (since I added the reference processing code a couple of 
> years ago) - we just never hit it.
>
> Anyway the assertion is caused by calling set_phase() - which throws 
> the assertion failure - after resetting the marking state - which 
> resets the value of the global finger.
>
> The solution was a three pronged approach:
>
> 1. Skip reference processing if the marking stack overflowed during 
> the actual remark task.
>
> This is safe to do as reference objects are only discovered once. So 
> once a reference object is discovered it will remain on the discovered 
> list until it is processed. Since, as a result of the overflow, 
> marking is going to restart - the references will be processed after a 
> successful remark. We could use the routine 
> abandon_partial_discovery() and depopulate the discovered lists but 
> the only benefit to doing this is that we may discover less references 
> during the subsequent restart.
>
> 2. Remove the set_phase() calls when we execute a new ref processing 
> proxy task
>
> To do this we need to call set_phase() from within weakRefsWork() and 
> call the terminator's reset_for_reuse() routine when we execute a new 
> ref processing task. This will remove the path that checks the assert.
>
> 3. Worker 0 only resets the marking state during the current phase of 
> marking.
>
> During the STW remark pause there is another call to reset the marking 
> stack (in the event of overflow) immediately after the discovered 
> references are processed:
>
>   double start = os::elapsedTime();
>
>   checkpointRootsFinalWork();
>
>   double mark_work_end = os::elapsedTime();
>
>   weakRefsWork(clear_all_soft_refs);
>
>   if (has_overflown()) {
>     // Oops. We overflowed. Restart concurrent marking.
>     _restart_for_overflow = true;
>     // Clear the marking state because we will be restarting
>     // marking due to overflowing the global mark stack.
>     reset_marking_state();
>     if (G1TraceMarkStackOverflow) {
>       gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
>     }
>
> I also fixed the British spelling of initialized in a few places.
>
> Testing:
> The lucene tests with parallel reference processing (with and without 
> verification).
> specjvm98 with parallel reference processing (with and without 
> verification).
>
> Thanks,
>
> JohnC



More information about the hotspot-gc-dev mailing list