Fri, 11 Apr 2014 11:00:12 +0200
8037112: gc/g1/TestHumongousAllocInitialMark.java caused SIGSEGV
Reviewed-by: brutisso, mgerdin
1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu May 22 09:12:29 2014 +0200 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Fri Apr 11 11:00:12 2014 +0200 1.3 @@ -89,6 +89,10 @@ 1.4 while (!_should_terminate) { 1.5 // wait until started is set. 1.6 sleepBeforeNextCycle(); 1.7 + if (_should_terminate) { 1.8 + break; 1.9 + } 1.10 + 1.11 { 1.12 ResourceMark rm; 1.13 HandleMark hm; 1.14 @@ -303,11 +307,21 @@ 1.15 } 1.16 1.17 void ConcurrentMarkThread::stop() { 1.18 - // it is ok to take late safepoints here, if needed 1.19 - MutexLockerEx mu(Terminator_lock); 1.20 - _should_terminate = true; 1.21 - while (!_has_terminated) { 1.22 - Terminator_lock->wait(); 1.23 + { 1.24 + MutexLockerEx ml(Terminator_lock); 1.25 + _should_terminate = true; 1.26 + } 1.27 + 1.28 + { 1.29 + MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag); 1.30 + CGC_lock->notify_all(); 1.31 + } 1.32 + 1.33 + { 1.34 + MutexLockerEx ml(Terminator_lock); 1.35 + while (!_has_terminated) { 1.36 + Terminator_lock->wait(); 1.37 + } 1.38 } 1.39 } 1.40 1.41 @@ -327,11 +341,14 @@ 1.42 assert(!in_progress(), "should have been cleared"); 1.43 1.44 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); 1.45 - while (!started()) { 1.46 + while (!started() && !_should_terminate) { 1.47 CGC_lock->wait(Mutex::_no_safepoint_check_flag); 1.48 } 1.49 - set_in_progress(); 1.50 - clear_started(); 1.51 + 1.52 + if (started()) { 1.53 + set_in_progress(); 1.54 + clear_started(); 1.55 + } 1.56 } 1.57 1.58 // Note: As is the case with CMS - this method, although exported
2.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu May 22 09:12:29 2014 +0200 2.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Apr 11 11:00:12 2014 +0200 2.3 @@ -435,6 +435,9 @@ 2.4 void G1CollectedHeap::stop_conc_gc_threads() { 2.5 _cg1r->stop(); 2.6 _cmThread->stop(); 2.7 + if (G1StringDedup::is_enabled()) { 2.8 + G1StringDedup::stop(); 2.9 + } 2.10 } 2.11 2.12 #ifdef ASSERT 2.13 @@ -2182,6 +2185,16 @@ 2.14 return JNI_OK; 2.15 } 2.16 2.17 +void G1CollectedHeap::stop() { 2.18 + // Abort any ongoing concurrent root region scanning and stop all 2.19 + // concurrent threads. We do this to make sure these threads do 2.20 + // not continue to execute and access resources (e.g. gclog_or_tty) 2.21 + // that are destroyed during shutdown. 2.22 + _cm->root_regions()->abort(); 2.23 + _cm->root_regions()->wait_until_scan_finished(); 2.24 + stop_conc_gc_threads(); 2.25 +} 2.26 + 2.27 size_t G1CollectedHeap::conservative_max_heap_alignment() { 2.28 return HeapRegion::max_region_size(); 2.29 }
3.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu May 22 09:12:29 2014 +0200 3.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Apr 11 11:00:12 2014 +0200 3.3 @@ -1082,6 +1082,8 @@ 3.4 // specified by the policy object. 3.5 jint initialize(); 3.6 3.7 + virtual void stop(); 3.8 + 3.9 // Return the (conservative) maximum heap alignment for any G1 heap 3.10 static size_t conservative_max_heap_alignment(); 3.11
4.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedup.cpp Thu May 22 09:12:29 2014 +0200 4.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedup.cpp Fri Apr 11 11:00:12 2014 +0200 4.3 @@ -44,6 +44,11 @@ 4.4 } 4.5 } 4.6 4.7 +void G1StringDedup::stop() { 4.8 + assert(is_enabled(), "String deduplication not enabled"); 4.9 + G1StringDedupThread::stop(); 4.10 +} 4.11 + 4.12 bool G1StringDedup::is_candidate_from_mark(oop obj) { 4.13 if (java_lang_String::is_instance(obj)) { 4.14 bool from_young = G1CollectedHeap::heap()->heap_region_containing_raw(obj)->is_young();
5.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedup.hpp Thu May 22 09:12:29 2014 +0200 5.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedup.hpp Fri Apr 11 11:00:12 2014 +0200 5.3 @@ -110,8 +110,12 @@ 5.4 return _enabled; 5.5 } 5.6 5.7 + // Initialize string deduplication. 5.8 static void initialize(); 5.9 5.10 + // Stop the deduplication thread. 5.11 + static void stop(); 5.12 + 5.13 // Immediately deduplicates the given String object, bypassing the 5.14 // the deduplication queue. 5.15 static void deduplicate(oop java_string);
6.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp Thu May 22 09:12:29 2014 +0200 6.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp Fri Apr 11 11:00:12 2014 +0200 6.3 @@ -35,6 +35,7 @@ 6.4 6.5 G1StringDedupQueue::G1StringDedupQueue() : 6.6 _cursor(0), 6.7 + _cancel(false), 6.8 _empty(true), 6.9 _dropped(0) { 6.10 _nqueues = MAX2(ParallelGCThreads, (size_t)1); 6.11 @@ -55,11 +56,17 @@ 6.12 6.13 void G1StringDedupQueue::wait() { 6.14 MonitorLockerEx ml(StringDedupQueue_lock, Mutex::_no_safepoint_check_flag); 6.15 - while (_queue->_empty) { 6.16 + while (_queue->_empty && !_queue->_cancel) { 6.17 ml.wait(Mutex::_no_safepoint_check_flag); 6.18 } 6.19 } 6.20 6.21 +void G1StringDedupQueue::cancel_wait() { 6.22 + MonitorLockerEx ml(StringDedupQueue_lock, Mutex::_no_safepoint_check_flag); 6.23 + _queue->_cancel = true; 6.24 + ml.notify(); 6.25 +} 6.26 + 6.27 void G1StringDedupQueue::push(uint worker_id, oop java_string) { 6.28 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint"); 6.29 assert(worker_id < _queue->_nqueues, "Invalid queue");
7.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedupQueue.hpp Thu May 22 09:12:29 2014 +0200 7.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedupQueue.hpp Fri Apr 11 11:00:12 2014 +0200 7.3 @@ -65,6 +65,7 @@ 7.4 G1StringDedupWorkerQueue* _queues; 7.5 size_t _nqueues; 7.6 size_t _cursor; 7.7 + bool _cancel; 7.8 volatile bool _empty; 7.9 7.10 // Statistics counter, only used for logging. 7.11 @@ -81,6 +82,9 @@ 7.12 // Blocks and waits for the queue to become non-empty. 7.13 static void wait(); 7.14 7.15 + // Wakes up any thread blocked waiting for the queue to become non-empty. 7.16 + static void cancel_wait(); 7.17 + 7.18 // Pushes a deduplication candidate onto a specific GC worker queue. 7.19 static void push(uint worker_id, oop java_string); 7.20
8.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp Thu May 22 09:12:29 2014 +0200 8.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp Fri Apr 11 11:00:12 2014 +0200 8.3 @@ -73,6 +73,9 @@ 8.4 8.5 // Wait for the queue to become non-empty 8.6 G1StringDedupQueue::wait(); 8.7 + if (_should_terminate) { 8.8 + break; 8.9 + } 8.10 8.11 // Include this thread in safepoints 8.12 stsJoin(); 8.13 @@ -108,7 +111,23 @@ 8.14 stsLeave(); 8.15 } 8.16 8.17 - ShouldNotReachHere(); 8.18 + terminate(); 8.19 +} 8.20 + 8.21 +void G1StringDedupThread::stop() { 8.22 + { 8.23 + MonitorLockerEx ml(Terminator_lock); 8.24 + _thread->_should_terminate = true; 8.25 + } 8.26 + 8.27 + G1StringDedupQueue::cancel_wait(); 8.28 + 8.29 + { 8.30 + MonitorLockerEx ml(Terminator_lock); 8.31 + while (!_thread->_has_terminated) { 8.32 + ml.wait(); 8.33 + } 8.34 + } 8.35 } 8.36 8.37 void G1StringDedupThread::print(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
9.1 --- a/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp Thu May 22 09:12:29 2014 +0200 9.2 +++ b/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp Fri Apr 11 11:00:12 2014 +0200 9.3 @@ -47,6 +47,8 @@ 9.4 9.5 public: 9.6 static void create(); 9.7 + static void stop(); 9.8 + 9.9 static G1StringDedupThread* thread(); 9.10 9.11 virtual void run();
10.1 --- a/src/share/vm/gc_interface/collectedHeap.hpp Thu May 22 09:12:29 2014 +0200 10.2 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Fri Apr 11 11:00:12 2014 +0200 10.3 @@ -208,6 +208,9 @@ 10.4 // This is the correct place to place such initialization methods. 10.5 virtual void post_initialize() = 0; 10.6 10.7 + // Stop any onging concurrent work and prepare for exit. 10.8 + virtual void stop() {} 10.9 + 10.10 MemRegion reserved_region() const { return _reserved; } 10.11 address base() const { return (address)reserved_region().start(); } 10.12
11.1 --- a/src/share/vm/runtime/java.cpp Thu May 22 09:12:29 2014 +0200 11.2 +++ b/src/share/vm/runtime/java.cpp Fri Apr 11 11:00:12 2014 +0200 11.3 @@ -497,6 +497,9 @@ 11.4 os::infinite_sleep(); 11.5 } 11.6 11.7 + // Stop any ongoing concurrent GC work 11.8 + Universe::heap()->stop(); 11.9 + 11.10 // Terminate watcher thread - must before disenrolling any periodic task 11.11 if (PeriodicTask::num_tasks() > 0) 11.12 WatcherThread::stop();