RFR (S): JDK-8046518: G1: Double calls to register_concurrent_cycle_end()
Bengt Rutisson
bengt.rutisson at oracle.com
Wed Jun 11 14:22:37 UTC 2014
Hi Stefan,
Thanks for looking at this!
On 6/11/14 1:10 PM, Stefan Karlsson wrote:
>
> On 2014-06-11 12:33, Bengt Rutisson wrote:
>>
>> Hi all,
>>
>> Can I have a review for this change?
>>
>> http://cr.openjdk.java.net/~brutisso/8046518/webrev.00/
>>
>> https://bugs.openjdk.java.net/browse/JDK-8046518
>>
>> Background:
>> When we abort a concurrent cycle due to a Full GC in G1 we call
>> ConcurrentMark::abort(). That will set _has_aborted flag and then
>> call register_concurrent_cycle_end().
>>
>> The concurrent marking thread will see the _has_aborted flag in its
>> ConcurrentMarkThread::run() method, abort the execution and then call
>> register_concurrent_cycle_end().
>>
>> Currently this works since the code inside
>> register_concurrent_cycle_end() is guarded by
>> _concurrent_cycle_started which it then resets. So, the double calls
>> will not necessarily result in too much extra work being done. But
>> one of the things that register_concurrent_cycle_end() does is to
>> call report_gc_end() on the concurrent GC tracer. That prevents
>> further use of it for this GC. This means that inside the
>> ConcurrentMarkThread::run() method we can not rely on the tracer.
>>
>> Removing the call to register_concurrent_cycle_end() in
>> ConcurrentMark::abort() and relying on the call in
>> ConcurrentMarkThread::run() seems to be a reasonable approach.
>
> The double call was deliberately put there to make sure that we end
> the tracing of the concurrent GC before starting to trace teh Full GC.
I figured there was a reason. I just couldn't remember. We would get
overlapping GC events without this extra call. Thanks for pointing that out!
> Why do you need to change this? I guess it has to do with your other
> GCId changes?
Right. It is for the GCId change. The problem is that calling
register_concurrent_cycle_end() will reset the GCId to be -1. When we
get to the logging, which is done in ConcurrentMarkThread::run(), I want
to add the GCId to this log entry:
if (cm()->has_aborted()) {
if (G1Log::fine()) {
gclog_or_tty->gclog_stamp(g1h->gc_tracer_cm()->gc_id());
gclog_or_tty->print_cr("[GC concurrent-mark-abort]");
}
}
But with the current code the GCId is always -1 here.
I guess one workaround I can do is to in abort() store the last aborted
GC id and use that for logging. It just seems a bit fragile that we
reset the concurrent gc tracer while we still have the concurrent mark
running.
Bengt
>
> thanks,
> StefanK
>
>>
>> Thanks,
>> Bengt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20140611/94325f68/attachment.htm>
More information about the hotspot-gc-dev
mailing list