提交 08630d11 编写于 作者: J johnc

7099824: G1: we should take the pending list lock before doing the remark pause

Summary: Acquire the pending list lock in the prologue method of G1's concurrent VM_Operation and release the lock in the epilogue() method. The locking/unlocking order of the pending list lock and the Heap_lock should match that in the prologue and epilogue methods of VM_GC_Operation.
Reviewed-by: tonyp, ysr
上级 80621b1d
...@@ -147,12 +147,8 @@ void ConcurrentMarkThread::run() { ...@@ -147,12 +147,8 @@ void ConcurrentMarkThread::run() {
} }
} }
} while (cm()->restart_for_overflow()); } while (cm()->restart_for_overflow());
double counting_start_time = os::elapsedVTime();
// YSR: These look dubious (i.e. redundant) !!! FIX ME
slt()->manipulatePLL(SurrogateLockerThread::acquirePLL);
slt()->manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
double counting_start_time = os::elapsedVTime();
if (!cm()->has_aborted()) { if (!cm()->has_aborted()) {
double count_start_sec = os::elapsedTime(); double count_start_sec = os::elapsedTime();
if (PrintGC) { if (PrintGC) {
...@@ -175,6 +171,7 @@ void ConcurrentMarkThread::run() { ...@@ -175,6 +171,7 @@ void ConcurrentMarkThread::run() {
} }
} }
} }
double end_time = os::elapsedVTime(); double end_time = os::elapsedVTime();
_vtime_count_accum += (end_time - counting_start_time); _vtime_count_accum += (end_time - counting_start_time);
// Update the total virtual time before doing this, since it will try // Update the total virtual time before doing this, since it will try
...@@ -335,13 +332,15 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() { ...@@ -335,13 +332,15 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() {
clear_started(); clear_started();
} }
// Note: this method, although exported by the ConcurrentMarkSweepThread, // Note: As is the case with CMS - this method, although exported
// which is a non-JavaThread, can only be called by a JavaThread. // by the ConcurrentMarkThread, which is a non-JavaThread, can only
// Currently this is done at vm creation time (post-vm-init) by the // be called by a JavaThread. Currently this is done at vm creation
// main/Primordial (Java)Thread. // time (post-vm-init) by the main/Primordial (Java)Thread.
// XXX Consider changing this in the future to allow the CMS thread // XXX Consider changing this in the future to allow the CM thread
// itself to create this thread? // itself to create this thread?
void ConcurrentMarkThread::makeSurrogateLockerThread(TRAPS) { void ConcurrentMarkThread::makeSurrogateLockerThread(TRAPS) {
assert(UseG1GC, "SLT thread needed only for concurrent GC");
assert(THREAD->is_Java_thread(), "must be a Java thread");
assert(_slt == NULL, "SLT already created"); assert(_slt == NULL, "SLT already created");
_slt = SurrogateLockerThread::make(THREAD); _slt = SurrogateLockerThread::make(THREAD);
} }
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp" #include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "gc_implementation/g1/vm_operations_g1.hpp" #include "gc_implementation/g1/vm_operations_g1.hpp"
...@@ -165,6 +166,20 @@ void VM_G1IncCollectionPause::doit_epilogue() { ...@@ -165,6 +166,20 @@ void VM_G1IncCollectionPause::doit_epilogue() {
} }
} }
void VM_CGC_Operation::acquire_pending_list_lock() {
// The caller may block while communicating
// with the SLT thread in order to acquire/release the PLL.
ConcurrentMarkThread::slt()->
manipulatePLL(SurrogateLockerThread::acquirePLL);
}
void VM_CGC_Operation::release_and_notify_pending_list_lock() {
// The caller may block while communicating
// with the SLT thread in order to acquire/release the PLL.
ConcurrentMarkThread::slt()->
manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
}
void VM_CGC_Operation::doit() { void VM_CGC_Operation::doit() {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
...@@ -180,12 +195,19 @@ void VM_CGC_Operation::doit() { ...@@ -180,12 +195,19 @@ void VM_CGC_Operation::doit() {
} }
bool VM_CGC_Operation::doit_prologue() { bool VM_CGC_Operation::doit_prologue() {
// Note the relative order of the locks must match that in
// VM_GC_Operation::doit_prologue() or deadlocks can occur
acquire_pending_list_lock();
Heap_lock->lock(); Heap_lock->lock();
SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true; SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
return true; return true;
} }
void VM_CGC_Operation::doit_epilogue() { void VM_CGC_Operation::doit_epilogue() {
// Note the relative order of the unlocks must match that in
// VM_GC_Operation::doit_epilogue()
SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false; SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
Heap_lock->unlock(); Heap_lock->unlock();
release_and_notify_pending_list_lock();
} }
...@@ -93,11 +93,17 @@ public: ...@@ -93,11 +93,17 @@ public:
} }
}; };
// Concurrent GC stop-the-world operations such as initial and final mark; // Concurrent GC stop-the-world operations such as remark and cleanup;
// consider sharing these with CMS's counterparts. // consider sharing these with CMS's counterparts.
class VM_CGC_Operation: public VM_Operation { class VM_CGC_Operation: public VM_Operation {
VoidClosure* _cl; VoidClosure* _cl;
const char* _printGCMessage; const char* _printGCMessage;
protected:
// java.lang.ref.Reference support
void acquire_pending_list_lock();
void release_and_notify_pending_list_lock();
public: public:
VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg) VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg)
: _cl(cl), _printGCMessage(printGCMsg) { } : _cl(cl), _printGCMessage(printGCMsg) { }
......
...@@ -224,6 +224,8 @@ void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { ...@@ -224,6 +224,8 @@ void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
assert(_buffer == empty, "Should be empty"); assert(_buffer == empty, "Should be empty");
assert(msg != empty, "empty message"); assert(msg != empty, "empty message");
assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread");
_buffer = msg; _buffer = msg;
while (_buffer != empty) { while (_buffer != empty) {
_monitor.notify(); _monitor.notify();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册