1659 return deflated; |
1659 return deflated; |
1660 } |
1660 } |
1661 |
1661 |
1662 // Walk a given monitor list, and deflate idle monitors |
1662 // Walk a given monitor list, and deflate idle monitors |
1663 // The given list could be a per-thread list or a global list |
1663 // The given list could be a per-thread list or a global list |
1664 // Caller acquires gListLock |
1664 // Caller acquires gListLock. |
|
1665 // |
|
1666 // In the case of parallel processing of thread local monitor lists, |
|
1667 // work is done by Threads::parallel_threads_do() which ensures that |
|
1668 // each Java thread is processed by exactly one worker thread, and |
|
1669 // thus avoid conflicts that would arise when worker threads would |
|
1670 // process the same monitor lists concurrently. |
|
1671 // |
|
1672 // See also ParallelSPCleanupTask and |
|
1673 // SafepointSynchronizer::do_cleanup_tasks() in safepoint.cpp and |
|
1674 // Threads::parallel_java_threads_do() in thread.cpp. |
1665 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp, |
1675 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp, |
1666 ObjectMonitor** freeHeadp, |
1676 ObjectMonitor** freeHeadp, |
1667 ObjectMonitor** freeTailp) { |
1677 ObjectMonitor** freeTailp) { |
1668 ObjectMonitor* mid; |
1678 ObjectMonitor* mid; |
1669 ObjectMonitor* next; |
1679 ObjectMonitor* next; |
1690 } |
1700 } |
1691 } |
1701 } |
1692 return deflated_count; |
1702 return deflated_count; |
1693 } |
1703 } |
1694 |
1704 |
1695 void ObjectSynchronizer::deflate_idle_monitors() { |
1705 void ObjectSynchronizer::prepare_deflate_idle_monitors(DeflateMonitorCounters* counters) { |
|
1706 counters->nInuse = 0; // currently associated with objects |
|
1707 counters->nInCirculation = 0; // extant |
|
1708 counters->nScavenged = 0; // reclaimed |
|
1709 } |
|
1710 |
|
1711 void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) { |
1696 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
1712 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
1697 int nInuse = 0; // currently associated with objects |
|
1698 int nInCirculation = 0; // extant |
|
1699 int nScavenged = 0; // reclaimed |
|
1700 bool deflated = false; |
1713 bool deflated = false; |
1701 |
1714 |
1702 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors |
1715 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors |
1703 ObjectMonitor * freeTailp = NULL; |
1716 ObjectMonitor * freeTailp = NULL; |
1704 |
1717 |
1707 // And in case the vm thread is acquiring a lock during a safepoint |
1720 // And in case the vm thread is acquiring a lock during a safepoint |
1708 // See e.g. 6320749 |
1721 // See e.g. 6320749 |
1709 Thread::muxAcquire(&gListLock, "scavenge - return"); |
1722 Thread::muxAcquire(&gListLock, "scavenge - return"); |
1710 |
1723 |
1711 if (MonitorInUseLists) { |
1724 if (MonitorInUseLists) { |
1712 int inUse = 0; |
1725 // Note: the thread-local monitors lists get deflated in |
1713 for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) { |
1726 // a separate pass. See deflate_thread_local_monitors(). |
1714 nInCirculation+= cur->omInUseCount; |
|
1715 int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp); |
|
1716 cur->omInUseCount-= deflated_count; |
|
1717 if (ObjectMonitor::Knob_VerifyInUse) { |
|
1718 verifyInUse(cur); |
|
1719 } |
|
1720 nScavenged += deflated_count; |
|
1721 nInuse += cur->omInUseCount; |
|
1722 } |
|
1723 |
1727 |
1724 // For moribund threads, scan gOmInUseList |
1728 // For moribund threads, scan gOmInUseList |
1725 if (gOmInUseList) { |
1729 if (gOmInUseList) { |
1726 nInCirculation += gOmInUseCount; |
1730 counters->nInCirculation += gOmInUseCount; |
1727 int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp); |
1731 int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp); |
1728 gOmInUseCount-= deflated_count; |
1732 gOmInUseCount -= deflated_count; |
1729 nScavenged += deflated_count; |
1733 counters->nScavenged += deflated_count; |
1730 nInuse += gOmInUseCount; |
1734 counters->nInuse += gOmInUseCount; |
1731 } |
1735 } |
1732 |
1736 |
1733 } else { |
1737 } else { |
1734 PaddedEnd<ObjectMonitor> * block = |
1738 PaddedEnd<ObjectMonitor> * block = |
1735 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); |
1739 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); |
1736 for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) { |
1740 for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) { |
1737 // Iterate over all extant monitors - Scavenge all idle monitors. |
1741 // Iterate over all extant monitors - Scavenge all idle monitors. |
1738 assert(block->object() == CHAINMARKER, "must be a block header"); |
1742 assert(block->object() == CHAINMARKER, "must be a block header"); |
1739 nInCirculation += _BLOCKSIZE; |
1743 counters->nInCirculation += _BLOCKSIZE; |
1740 for (int i = 1; i < _BLOCKSIZE; i++) { |
1744 for (int i = 1; i < _BLOCKSIZE; i++) { |
1741 ObjectMonitor* mid = (ObjectMonitor*)&block[i]; |
1745 ObjectMonitor* mid = (ObjectMonitor*)&block[i]; |
1742 oop obj = (oop)mid->object(); |
1746 oop obj = (oop)mid->object(); |
1743 |
1747 |
1744 if (obj == NULL) { |
1748 if (obj == NULL) { |
1751 } |
1755 } |
1752 deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp); |
1756 deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp); |
1753 |
1757 |
1754 if (deflated) { |
1758 if (deflated) { |
1755 mid->FreeNext = NULL; |
1759 mid->FreeNext = NULL; |
1756 nScavenged++; |
1760 counters->nScavenged++; |
1757 } else { |
1761 } else { |
1758 nInuse++; |
1762 counters->nInuse++; |
1759 } |
1763 } |
1760 } |
1764 } |
1761 } |
1765 } |
1762 } |
1766 } |
1763 |
1767 |
1764 gMonitorFreeCount += nScavenged; |
|
1765 |
|
1766 // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree. |
|
1767 |
|
1768 if (ObjectMonitor::Knob_Verbose) { |
|
1769 tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d " |
|
1770 "ForceMonitorScavenge=%d : pop=%d free=%d", |
|
1771 nInCirculation, nInuse, nScavenged, ForceMonitorScavenge, |
|
1772 gMonitorPopulation, gMonitorFreeCount); |
|
1773 tty->flush(); |
|
1774 } |
|
1775 |
|
1776 ForceMonitorScavenge = 0; // Reset |
|
1777 |
|
1778 // Move the scavenged monitors back to the global free list. |
1768 // Move the scavenged monitors back to the global free list. |
1779 if (freeHeadp != NULL) { |
1769 if (freeHeadp != NULL) { |
1780 guarantee(freeTailp != NULL && nScavenged > 0, "invariant"); |
1770 guarantee(freeTailp != NULL && counters->nScavenged > 0, "invariant"); |
1781 assert(freeTailp->FreeNext == NULL, "invariant"); |
1771 assert(freeTailp->FreeNext == NULL, "invariant"); |
1782 // constant-time list splice - prepend scavenged segment to gFreeList |
1772 // constant-time list splice - prepend scavenged segment to gFreeList |
1783 freeTailp->FreeNext = gFreeList; |
1773 freeTailp->FreeNext = gFreeList; |
1784 gFreeList = freeHeadp; |
1774 gFreeList = freeHeadp; |
1785 } |
1775 } |
1786 Thread::muxRelease(&gListLock); |
1776 Thread::muxRelease(&gListLock); |
1787 |
1777 |
1788 OM_PERFDATA_OP(Deflations, inc(nScavenged)); |
1778 } |
1789 OM_PERFDATA_OP(MonExtant, set_value(nInCirculation)); |
1779 |
|
1780 void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* counters) { |
|
1781 gMonitorFreeCount += counters->nScavenged; |
|
1782 |
|
1783 // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree. |
|
1784 |
|
1785 if (ObjectMonitor::Knob_Verbose) { |
|
1786 tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d " |
|
1787 "ForceMonitorScavenge=%d : pop=%d free=%d", |
|
1788 counters->nInCirculation, counters->nInuse, counters->nScavenged, ForceMonitorScavenge, |
|
1789 gMonitorPopulation, gMonitorFreeCount); |
|
1790 tty->flush(); |
|
1791 } |
|
1792 |
|
1793 ForceMonitorScavenge = 0; // Reset |
|
1794 |
|
1795 OM_PERFDATA_OP(Deflations, inc(counters->nScavenged)); |
|
1796 OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation)); |
1790 |
1797 |
1791 // TODO: Add objectMonitor leak detection. |
1798 // TODO: Add objectMonitor leak detection. |
1792 // Audit/inventory the objectMonitors -- make sure they're all accounted for. |
1799 // Audit/inventory the objectMonitors -- make sure they're all accounted for. |
1793 GVars.stwRandom = os::random(); |
1800 GVars.stwRandom = os::random(); |
1794 GVars.stwCycle++; |
1801 GVars.stwCycle++; |
|
1802 } |
|
1803 |
|
1804 void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) { |
|
1805 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
|
1806 if (!MonitorInUseLists) return; |
|
1807 |
|
1808 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors |
|
1809 ObjectMonitor * freeTailp = NULL; |
|
1810 |
|
1811 int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp); |
|
1812 |
|
1813 Thread::muxAcquire(&gListLock, "scavenge - return"); |
|
1814 |
|
1815 // Adjust counters |
|
1816 counters->nInCirculation += thread->omInUseCount; |
|
1817 thread->omInUseCount -= deflated_count; |
|
1818 if (ObjectMonitor::Knob_VerifyInUse) { |
|
1819 verifyInUse(thread); |
|
1820 } |
|
1821 counters->nScavenged += deflated_count; |
|
1822 counters->nInuse += thread->omInUseCount; |
|
1823 |
|
1824 // Move the scavenged monitors back to the global free list. |
|
1825 if (freeHeadp != NULL) { |
|
1826 guarantee(freeTailp != NULL && deflated_count > 0, "invariant"); |
|
1827 assert(freeTailp->FreeNext == NULL, "invariant"); |
|
1828 |
|
1829 // constant-time list splice - prepend scavenged segment to gFreeList |
|
1830 freeTailp->FreeNext = gFreeList; |
|
1831 gFreeList = freeHeadp; |
|
1832 } |
|
1833 Thread::muxRelease(&gListLock); |
1795 } |
1834 } |
1796 |
1835 |
1797 // Monitor cleanup on JavaThread::exit |
1836 // Monitor cleanup on JavaThread::exit |
1798 |
1837 |
1799 // Iterate through monitor cache and attempt to release thread's monitors |
1838 // Iterate through monitor cache and attempt to release thread's monitors |