# HG changeset patch # User brutisso # Date 1454935137 -3600 # Mon Feb 08 13:38:57 2016 +0100 # Node ID 1156d47e39377a477e0b2179faab2f1b62878e3e # Parent 3472ec7733c2763ac323386aa697f0653d66bf3a [mq]: hang diff --git a/src/share/vm/gc/g1/concurrentMarkThread.cpp b/src/share/vm/gc/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc/g1/concurrentMarkThread.cpp +++ b/src/share/vm/gc/g1/concurrentMarkThread.cpp @@ -123,6 +123,7 @@ // wait until started is set. sleepBeforeNextCycle(); if (_should_terminate) { + _cm->root_regions()->cancel_scan(); break; } @@ -140,10 +141,9 @@ // without the root regions have been scanned which would be a // correctness issue. - if (!cm()->has_aborted()) { - GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); - _cm->scanRootRegions(); - } + assert(!cm()->has_aborted(), "Aborting before root region scanning is finished not supported."); + GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); + _cm->scanRootRegions(); // It would be nice to use the GCTraceConcTime class here but // the "end" logging is inside the loop and not at the end of diff --git a/src/share/vm/gc/g1/g1CollectedHeap.cpp b/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -1290,8 +1290,7 @@ ref_processor_cm()->verify_no_references_recorded(); // Abandon current iterations of concurrent marking and concurrent - // refinement, if any are in progress. We have to do this before - // wait_until_scan_finished() below. + // refinement, if any are in progress. concurrent_mark()->abort(); // Make sure we'll choose a new allocation region afterwards. diff --git a/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/src/share/vm/gc/g1/g1ConcurrentMark.cpp --- a/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -372,6 +372,12 @@ return res; } +void G1CMRootRegions::cancel_scan() { + MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag); + _scan_in_progress = false; + RootRegionScan_lock->notify_all(); +} + void G1CMRootRegions::scan_finished() { assert(scan_in_progress(), "pre-condition"); diff --git a/src/share/vm/gc/g1/g1ConcurrentMark.hpp b/src/share/vm/gc/g1/g1ConcurrentMark.hpp --- a/src/share/vm/gc/g1/g1ConcurrentMark.hpp +++ b/src/share/vm/gc/g1/g1ConcurrentMark.hpp @@ -248,6 +248,8 @@ // all have been claimed. HeapRegion* claim_next(); + void cancel_scan(); + // Flag that we're done with root region scanning and notify anyone // who's waiting on it. If aborted is false, assume that all regions // have been claimed. # HG changeset patch # User brutisso # Date 1454940301 -3600 # Mon Feb 08 15:05:01 2016 +0100 # Node ID 0888bb4acd9cadfa245845cc043343736b130634 # Parent 1156d47e39377a477e0b2179faab2f1b62878e3e [mq]: if-assert diff --git a/src/share/vm/gc/g1/concurrentMarkThread.cpp b/src/share/vm/gc/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc/g1/concurrentMarkThread.cpp +++ b/src/share/vm/gc/g1/concurrentMarkThread.cpp @@ -141,9 +141,11 @@ // without the root regions have been scanned which would be a // correctness issue. - assert(!cm()->has_aborted(), "Aborting before root region scanning is finished not supported."); - GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); - _cm->scanRootRegions(); + if (_cm->root_regions()->scan_in_progress()) { + assert(!cm()->has_aborted(), "Aborting before root region scanning is finished not supported."); + GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); + _cm->scanRootRegions(); + } // It would be nice to use the GCTraceConcTime class here but // the "end" logging is inside the loop and not at the end of diff --git a/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/src/share/vm/gc/g1/g1ConcurrentMark.cpp --- a/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -372,12 +372,16 @@ return res; } -void G1CMRootRegions::cancel_scan() { +void G1CMRootRegions::notify_scan_done() { MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag); _scan_in_progress = false; RootRegionScan_lock->notify_all(); } +void G1CMRootRegions::cancel_scan() { + notify_scan_done(); +} + void G1CMRootRegions::scan_finished() { assert(scan_in_progress(), "pre-condition"); @@ -387,11 +391,7 @@ } _next_survivor = NULL; - { - MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag); - _scan_in_progress = false; - RootRegionScan_lock->notify_all(); - } + notify_scan_done(); } bool G1CMRootRegions::wait_until_scan_finished() { diff --git a/src/share/vm/gc/g1/g1ConcurrentMark.hpp b/src/share/vm/gc/g1/g1ConcurrentMark.hpp --- a/src/share/vm/gc/g1/g1ConcurrentMark.hpp +++ b/src/share/vm/gc/g1/g1ConcurrentMark.hpp @@ -229,6 +229,8 @@ volatile bool _should_abort; HeapRegion* volatile _next_survivor; + void notify_scan_done(); + public: G1CMRootRegions(); // We actually do most of the initialization in this method. # HG changeset patch # User brutisso # Date 1455093351 -3600 # Wed Feb 10 09:35:51 2016 +0100 # Node ID 70ce930e82741ef7ef407220024ea6f13b2e0b1b # Parent 0888bb4acd9cadfa245845cc043343736b130634 imported patch fix diff --git a/src/share/vm/gc/g1/concurrentMarkThread.cpp b/src/share/vm/gc/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc/g1/concurrentMarkThread.cpp +++ b/src/share/vm/gc/g1/concurrentMarkThread.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" @@ -133,6 +134,11 @@ HandleMark hm; double cycle_start = os::elapsedVTime(); + { + GCConcPhaseTimer(_cm, "Concurrent Clearing of Claimed Marks"); + ClassLoaderDataGraph::clear_claimed_marks(); + } + // We have to ensure that we finish scanning the root regions // before the next GC takes place. To ensure this we have to // make sure that we do not join the STS until the root regions @@ -141,8 +147,7 @@ // without the root regions have been scanned which would be a // correctness issue. - if (_cm->root_regions()->scan_in_progress()) { - assert(!cm()->has_aborted(), "Aborting before root region scanning is finished not supported."); + { GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); _cm->scanRootRegions(); } diff --git a/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/src/share/vm/gc/g1/g1ConcurrentMark.cpp --- a/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -984,13 +984,11 @@ }; void G1ConcurrentMark::scanRootRegions() { - // Start of concurrent marking. - ClassLoaderDataGraph::clear_claimed_marks(); - // scan_in_progress() will have been set to true only if there was // at least one root region to scan. So, if it's false, we // should not attempt to do any further work. if (root_regions()->scan_in_progress()) { + assert(!has_aborted(), "Aborting before root region scanning is finished not supported."); GCTraceConcTime(Info, gc) tt("Concurrent Root Region Scan"); _parallel_marking_threads = calc_parallel_marking_threads(); diff --git a/src/share/vm/gc/g1/g1HeapVerifier.cpp b/src/share/vm/gc/g1/g1HeapVerifier.cpp --- a/src/share/vm/gc/g1/g1HeapVerifier.cpp +++ b/src/share/vm/gc/g1/g1HeapVerifier.cpp @@ -408,7 +408,7 @@ // print_extended_on() instead of print_on(). LogHandle(gc, verify) log; ResourceMark rm; - _g1h->print_extended_on(log.info_stream()); + _g1h->print_extended_on(log.error_stream()); } guarantee(!failures, "there should not have been any failures"); }