mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
6660573: G1: BigApps Failure : guarantee(satb_mq_set.completed_buffers_num() == 0,"invariant") When exiting a mutator thread is removed from the thread list before it has a chance to flush its SATB and barrier queues. If GC happens at this moment the objects that are refererred from these queues can be moved, which will case a crash. The fix is simply to flush the buffers before removing a thread from the list. Reviewed-by: jcoomes, tonyp
This commit is contained in:
parent
98685a4d93
commit
cbf1c89d60
4 changed files with 58 additions and 29 deletions
|
@ -30,7 +30,7 @@ PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) :
|
|||
_perm(perm), _lock(NULL)
|
||||
{}
|
||||
|
||||
PtrQueue::~PtrQueue() {
|
||||
void PtrQueue::flush() {
|
||||
if (!_perm && _buf != NULL) {
|
||||
if (_index == _sz) {
|
||||
// No work to do.
|
||||
|
@ -41,8 +41,9 @@ PtrQueue::~PtrQueue() {
|
|||
_buf[byte_index_to_index((int)i)] = NULL;
|
||||
}
|
||||
qset()->enqueue_complete_buffer(_buf);
|
||||
_buf = NULL;
|
||||
}
|
||||
_buf = NULL;
|
||||
_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,9 @@ public:
|
|||
// given PtrQueueSet.
|
||||
PtrQueue(PtrQueueSet*, bool perm = false);
|
||||
// Release any contained resources.
|
||||
~PtrQueue();
|
||||
void flush();
|
||||
// Calls flush() when destroyed.
|
||||
~PtrQueue() { flush(); }
|
||||
|
||||
// Associate a lock with a ptr queue.
|
||||
void set_lock(Mutex* lock) { _lock = lock; }
|
||||
|
|
|
@ -1422,6 +1422,7 @@ static void ensure_join(JavaThread* thread) {
|
|||
thread->clear_pending_exception();
|
||||
}
|
||||
|
||||
|
||||
// For any new cleanup additions, please check to see if they need to be applied to
|
||||
// cleanup_failed_attach_current_thread as well.
|
||||
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||
|
@ -1592,12 +1593,27 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
|||
JvmtiExport::cleanup_thread(this);
|
||||
}
|
||||
|
||||
#ifndef SERIALGC
|
||||
// We must flush G1-related buffers before removing a thread from
|
||||
// the list of active threads.
|
||||
if (UseG1GC) {
|
||||
flush_barrier_queues();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
||||
Threads::remove(this);
|
||||
}
|
||||
|
||||
void JavaThread::cleanup_failed_attach_current_thread() {
|
||||
#ifndef SERIALGC
|
||||
// Flush G1-related queues.
|
||||
void JavaThread::flush_barrier_queues() {
|
||||
satb_mark_queue().flush();
|
||||
dirty_card_queue().flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
void JavaThread::cleanup_failed_attach_current_thread() {
|
||||
if (get_thread_profiler() != NULL) {
|
||||
get_thread_profiler()->disengage();
|
||||
ResourceMark rm;
|
||||
|
@ -1620,11 +1636,19 @@ void JavaThread::cleanup_failed_attach_current_thread() {
|
|||
tlab().make_parsable(true); // retire TLAB, if any
|
||||
}
|
||||
|
||||
#ifndef SERIALGC
|
||||
if (UseG1GC) {
|
||||
flush_barrier_queues();
|
||||
}
|
||||
#endif
|
||||
|
||||
Threads::remove(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JavaThread* JavaThread::active() {
|
||||
Thread* thread = ThreadLocalStorage::thread();
|
||||
assert(thread != NULL, "just checking");
|
||||
|
|
|
@ -793,6 +793,8 @@ class JavaThread: public Thread {
|
|||
DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards.
|
||||
// Set of all such queues.
|
||||
static DirtyCardQueueSet _dirty_card_queue_set;
|
||||
|
||||
void flush_barrier_queues();
|
||||
#endif // !SERIALGC
|
||||
|
||||
friend class VMThread;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue