mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +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
|
@ -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,37 +1593,60 @@ 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() {
|
||||
|
||||
if (get_thread_profiler() != NULL) {
|
||||
get_thread_profiler()->disengage();
|
||||
ResourceMark rm;
|
||||
get_thread_profiler()->print(get_thread_name());
|
||||
}
|
||||
|
||||
if (active_handles() != NULL) {
|
||||
JNIHandleBlock* block = active_handles();
|
||||
set_active_handles(NULL);
|
||||
JNIHandleBlock::release_block(block);
|
||||
}
|
||||
|
||||
if (free_handle_block() != NULL) {
|
||||
JNIHandleBlock* block = free_handle_block();
|
||||
set_free_handle_block(NULL);
|
||||
JNIHandleBlock::release_block(block);
|
||||
}
|
||||
|
||||
if (UseTLAB) {
|
||||
tlab().make_parsable(true); // retire TLAB, if any
|
||||
}
|
||||
|
||||
Threads::remove(this);
|
||||
delete this;
|
||||
#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;
|
||||
get_thread_profiler()->print(get_thread_name());
|
||||
}
|
||||
|
||||
if (active_handles() != NULL) {
|
||||
JNIHandleBlock* block = active_handles();
|
||||
set_active_handles(NULL);
|
||||
JNIHandleBlock::release_block(block);
|
||||
}
|
||||
|
||||
if (free_handle_block() != NULL) {
|
||||
JNIHandleBlock* block = free_handle_block();
|
||||
set_free_handle_block(NULL);
|
||||
JNIHandleBlock::release_block(block);
|
||||
}
|
||||
|
||||
if (UseTLAB) {
|
||||
tlab().make_parsable(true); // retire TLAB, if any
|
||||
}
|
||||
|
||||
#ifndef SERIALGC
|
||||
if (UseG1GC) {
|
||||
flush_barrier_queues();
|
||||
}
|
||||
#endif
|
||||
|
||||
Threads::remove(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JavaThread* JavaThread::active() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue