comparison src/share/vm/runtime/thread.cpp @ 441:da9cb4e97a5f

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") Summary: 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
author iveresov
date Fri, 14 Nov 2008 14:23:05 -0800
parents 99dd4bbd9eec
children eca19a8425b5
comparison
equal deleted inserted replaced
440:96c6da8f095c 441:da9cb4e97a5f
1419 java_lang_Thread::set_thread(threadObj(), NULL); 1419 java_lang_Thread::set_thread(threadObj(), NULL);
1420 lock.notify_all(thread); 1420 lock.notify_all(thread);
1421 // Ignore pending exception (ThreadDeath), since we are exiting anyway 1421 // Ignore pending exception (ThreadDeath), since we are exiting anyway
1422 thread->clear_pending_exception(); 1422 thread->clear_pending_exception();
1423 } 1423 }
1424
1424 1425
1425 // For any new cleanup additions, please check to see if they need to be applied to 1426 // For any new cleanup additions, please check to see if they need to be applied to
1426 // cleanup_failed_attach_current_thread as well. 1427 // cleanup_failed_attach_current_thread as well.
1427 void JavaThread::exit(bool destroy_vm, ExitType exit_type) { 1428 void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
1428 assert(this == JavaThread::current(), "thread consistency check"); 1429 assert(this == JavaThread::current(), "thread consistency check");
1590 1591
1591 if (jvmti_thread_state() != NULL) { 1592 if (jvmti_thread_state() != NULL) {
1592 JvmtiExport::cleanup_thread(this); 1593 JvmtiExport::cleanup_thread(this);
1593 } 1594 }
1594 1595
1596 #ifndef SERIALGC
1597 // We must flush G1-related buffers before removing a thread from
1598 // the list of active threads.
1599 if (UseG1GC) {
1600 flush_barrier_queues();
1601 }
1602 #endif
1603
1595 // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread 1604 // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
1596 Threads::remove(this); 1605 Threads::remove(this);
1597 } 1606 }
1598 1607
1608 #ifndef SERIALGC
1609 // Flush G1-related queues.
1610 void JavaThread::flush_barrier_queues() {
1611 satb_mark_queue().flush();
1612 dirty_card_queue().flush();
1613 }
1614 #endif
1615
1599 void JavaThread::cleanup_failed_attach_current_thread() { 1616 void JavaThread::cleanup_failed_attach_current_thread() {
1600 1617 if (get_thread_profiler() != NULL) {
1601 if (get_thread_profiler() != NULL) { 1618 get_thread_profiler()->disengage();
1602 get_thread_profiler()->disengage(); 1619 ResourceMark rm;
1603 ResourceMark rm; 1620 get_thread_profiler()->print(get_thread_name());
1604 get_thread_profiler()->print(get_thread_name()); 1621 }
1605 } 1622
1606 1623 if (active_handles() != NULL) {
1607 if (active_handles() != NULL) { 1624 JNIHandleBlock* block = active_handles();
1608 JNIHandleBlock* block = active_handles(); 1625 set_active_handles(NULL);
1609 set_active_handles(NULL); 1626 JNIHandleBlock::release_block(block);
1610 JNIHandleBlock::release_block(block); 1627 }
1611 } 1628
1612 1629 if (free_handle_block() != NULL) {
1613 if (free_handle_block() != NULL) { 1630 JNIHandleBlock* block = free_handle_block();
1614 JNIHandleBlock* block = free_handle_block(); 1631 set_free_handle_block(NULL);
1615 set_free_handle_block(NULL); 1632 JNIHandleBlock::release_block(block);
1616 JNIHandleBlock::release_block(block); 1633 }
1617 } 1634
1618 1635 if (UseTLAB) {
1619 if (UseTLAB) { 1636 tlab().make_parsable(true); // retire TLAB, if any
1620 tlab().make_parsable(true); // retire TLAB, if any 1637 }
1621 } 1638
1622 1639 #ifndef SERIALGC
1623 Threads::remove(this); 1640 if (UseG1GC) {
1624 delete this; 1641 flush_barrier_queues();
1625 } 1642 }
1643 #endif
1644
1645 Threads::remove(this);
1646 delete this;
1647 }
1648
1649
1626 1650
1627 1651
1628 JavaThread* JavaThread::active() { 1652 JavaThread* JavaThread::active() {
1629 Thread* thread = ThreadLocalStorage::thread(); 1653 Thread* thread = ThreadLocalStorage::thread();
1630 assert(thread != NULL, "just checking"); 1654 assert(thread != NULL, "just checking");