Mercurial > hg > truffle
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"); |