1676 if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
1677 // if deflate_monitor succeeded,
1678 // extract from per-thread in-use list
1679 if (mid == *listHeadp) {
1680 *listHeadp = mid->FreeNext;
1681 } else if (cur_mid_in_use != NULL) {
1682 cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
1683 }
1684 next = mid->FreeNext;
1685 mid->FreeNext = NULL; // This mid is current tail in the freeHeadp list
1686 mid = next;
1687 deflated_count++;
1688 } else {
1689 cur_mid_in_use = mid;
1690 mid = mid->FreeNext;
1691 }
1692 }
1693 return deflated_count;
1694 }
1695
1696 void ObjectSynchronizer::deflate_idle_monitors() {
1697 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1698 int nInuse = 0; // currently associated with objects
1699 int nInCirculation = 0; // extant
1700 int nScavenged = 0; // reclaimed
1701 bool deflated = false;
1702
1703 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
1704 ObjectMonitor * freeTailp = NULL;
1705
1706 TEVENT(deflate_idle_monitors);
1707 // Prevent omFlush from changing mids in Thread dtor's during deflation
1708 // And in case the vm thread is acquiring a lock during a safepoint
1709 // See e.g. 6320749
1710 Thread::muxAcquire(&gListLock, "scavenge - return");
1711
1712 if (MonitorInUseLists) {
1713 int inUse = 0;
1714 for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
1715 nInCirculation+= cur->omInUseCount;
1716 int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
1717 cur->omInUseCount-= deflated_count;
1718 if (ObjectMonitor::Knob_VerifyInUse) {
1719 verifyInUse(cur);
1720 }
1721 nScavenged += deflated_count;
1722 nInuse += cur->omInUseCount;
1723 }
1724
1725 // For moribund threads, scan gOmInUseList
1726 if (gOmInUseList) {
1727 nInCirculation += gOmInUseCount;
1728 int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1729 gOmInUseCount-= deflated_count;
1730 nScavenged += deflated_count;
1731 nInuse += gOmInUseCount;
1732 }
1733
1734 } else {
1735 PaddedEnd<ObjectMonitor> * block =
1736 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1737 for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1738 // Iterate over all extant monitors - Scavenge all idle monitors.
1739 assert(block->object() == CHAINMARKER, "must be a block header");
1740 nInCirculation += _BLOCKSIZE;
1741 for (int i = 1; i < _BLOCKSIZE; i++) {
1742 ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1743 oop obj = (oop)mid->object();
1744
1745 if (obj == NULL) {
1746 // The monitor is not associated with an object.
1747 // The monitor should either be a thread-specific private
1748 // free list or the global free list.
1749 // obj == NULL IMPLIES mid->is_busy() == 0
1750 guarantee(!mid->is_busy(), "invariant");
1751 continue;
1752 }
1753 deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
1754
1755 if (deflated) {
1756 mid->FreeNext = NULL;
1757 nScavenged++;
1758 } else {
1759 nInuse++;
1760 }
1761 }
1762 }
1763 }
1764
1765 gMonitorFreeCount += nScavenged;
1766
1767 // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree.
1768
1769 if (ObjectMonitor::Knob_Verbose) {
1770 tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d "
1771 "ForceMonitorScavenge=%d : pop=%d free=%d",
1772 nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
1773 gMonitorPopulation, gMonitorFreeCount);
1774 tty->flush();
1775 }
1776
1777 ForceMonitorScavenge = 0; // Reset
1778
1779 // Move the scavenged monitors back to the global free list.
1780 if (freeHeadp != NULL) {
1781 guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1782 assert(freeTailp->FreeNext == NULL, "invariant");
1783 // constant-time list splice - prepend scavenged segment to gFreeList
1784 freeTailp->FreeNext = gFreeList;
1785 gFreeList = freeHeadp;
1786 }
1787 Thread::muxRelease(&gListLock);
1788
1789 OM_PERFDATA_OP(Deflations, inc(nScavenged));
1790 OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
1791
1792 // TODO: Add objectMonitor leak detection.
1793 // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1794 GVars.stwRandom = os::random();
1795 GVars.stwCycle++;
1796 }
1797
1798 // Monitor cleanup on JavaThread::exit
1799
1800 // Iterate through monitor cache and attempt to release thread's monitors
1801 // Gives up on a particular monitor if an exception occurs, but continues
1802 // the overall iteration, swallowing the exception.
1803 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1804 private:
1805 TRAPS;
1806
1807 public:
1808 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1809 void do_monitor(ObjectMonitor* mid) {
1810 if (mid->owner() == THREAD) {
1811 if (ObjectMonitor::Knob_VerifyMatch != 0) {
1812 ResourceMark rm;
1813 Handle obj(THREAD, (oop) mid->object());
1814 tty->print("INFO: unexpected locked object:");
1815 javaVFrame::print_locked_object_class_name(tty, obj, "locked");
|
1676 if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
1677 // if deflate_monitor succeeded,
1678 // extract from per-thread in-use list
1679 if (mid == *listHeadp) {
1680 *listHeadp = mid->FreeNext;
1681 } else if (cur_mid_in_use != NULL) {
1682 cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
1683 }
1684 next = mid->FreeNext;
1685 mid->FreeNext = NULL; // This mid is current tail in the freeHeadp list
1686 mid = next;
1687 deflated_count++;
1688 } else {
1689 cur_mid_in_use = mid;
1690 mid = mid->FreeNext;
1691 }
1692 }
1693 return deflated_count;
1694 }
1695
1696 void ObjectSynchronizer::prepare_deflate_idle_monitors(DeflateMonitorCounters* counters) {
1697 counters->nInuse = 0; // currently associated with objects
1698 counters->nInCirculation = 0; // extant
1699 counters->nScavenged = 0; // reclaimed
1700 }
1701
1702 void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) {
1703 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1704 bool deflated = false;
1705
1706 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
1707 ObjectMonitor * freeTailp = NULL;
1708
1709 TEVENT(deflate_idle_monitors);
1710 // Prevent omFlush from changing mids in Thread dtor's during deflation
1711 // And in case the vm thread is acquiring a lock during a safepoint
1712 // See e.g. 6320749
1713 Thread::muxAcquire(&gListLock, "scavenge - return");
1714
1715 if (MonitorInUseLists) {
1716 // Note: the thread-local monitors lists get deflated in
1717 // a separate pass. See deflate_thread_local_monitors().
1718
1719 // For moribund threads, scan gOmInUseList
1720 if (gOmInUseList) {
1721 counters->nInCirculation += gOmInUseCount;
1722 int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1723 gOmInUseCount-= deflated_count;
1724 counters->nScavenged += deflated_count;
1725 counters->nInuse += gOmInUseCount;
1726 }
1727
1728 } else {
1729 PaddedEnd<ObjectMonitor> * block =
1730 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1731 for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1732 // Iterate over all extant monitors - Scavenge all idle monitors.
1733 assert(block->object() == CHAINMARKER, "must be a block header");
1734 counters->nInCirculation += _BLOCKSIZE;
1735 for (int i = 1; i < _BLOCKSIZE; i++) {
1736 ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1737 oop obj = (oop)mid->object();
1738
1739 if (obj == NULL) {
1740 // The monitor is not associated with an object.
1741 // The monitor should either be a thread-specific private
1742 // free list or the global free list.
1743 // obj == NULL IMPLIES mid->is_busy() == 0
1744 guarantee(!mid->is_busy(), "invariant");
1745 continue;
1746 }
1747 deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
1748
1749 if (deflated) {
1750 mid->FreeNext = NULL;
1751 counters->nScavenged++;
1752 } else {
1753 counters->nInuse++;
1754 }
1755 }
1756 }
1757 }
1758
1759 // Move the scavenged monitors back to the global free list.
1760 if (freeHeadp != NULL) {
1761 guarantee(freeTailp != NULL && counters->nScavenged > 0, "invariant");
1762 assert(freeTailp->FreeNext == NULL, "invariant");
1763 // constant-time list splice - prepend scavenged segment to gFreeList
1764 freeTailp->FreeNext = gFreeList;
1765 gFreeList = freeHeadp;
1766 }
1767 Thread::muxRelease(&gListLock);
1768
1769 }
1770
1771 void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* counters) {
1772 gMonitorFreeCount += counters->nScavenged;
1773
1774 // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree.
1775
1776 if (ObjectMonitor::Knob_Verbose) {
1777 tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d "
1778 "ForceMonitorScavenge=%d : pop=%d free=%d",
1779 counters->nInCirculation, counters->nInuse, counters->nScavenged, ForceMonitorScavenge,
1780 gMonitorPopulation, gMonitorFreeCount);
1781 tty->flush();
1782 }
1783
1784 ForceMonitorScavenge = 0; // Reset
1785
1786 OM_PERFDATA_OP(Deflations, inc(counters->nScavenged));
1787 OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation));
1788
1789 // TODO: Add objectMonitor leak detection.
1790 // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1791 GVars.stwRandom = os::random();
1792 GVars.stwCycle++;
1793 }
1794
1795 void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) {
1796 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1797 if (! MonitorInUseLists) return;
1798
1799 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
1800 ObjectMonitor * freeTailp = NULL;
1801
1802 int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
1803
1804 Thread::muxAcquire(&gListLock, "scavenge - return");
1805
1806 // Adjust counters
1807 counters->nInCirculation += thread->omInUseCount;
1808 thread->omInUseCount-= deflated_count;
1809 if (ObjectMonitor::Knob_VerifyInUse) {
1810 verifyInUse(thread);
1811 }
1812 counters->nScavenged += deflated_count;
1813 counters->nInuse += thread->omInUseCount;
1814 gMonitorFreeCount += deflated_count;
1815
1816 // Move the scavenged monitors back to the global free list.
1817 if (freeHeadp != NULL) {
1818 guarantee(freeTailp != NULL && deflated_count > 0, "invariant");
1819 assert(freeTailp->FreeNext == NULL, "invariant");
1820
1821 // constant-time list splice - prepend scavenged segment to gFreeList
1822 freeTailp->FreeNext = gFreeList;
1823 gFreeList = freeHeadp;
1824 }
1825 Thread::muxRelease(&gListLock);
1826 }
1827
1828 // Monitor cleanup on JavaThread::exit
1829
1830 // Iterate through monitor cache and attempt to release thread's monitors
1831 // Gives up on a particular monitor if an exception occurs, but continues
1832 // the overall iteration, swallowing the exception.
1833 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1834 private:
1835 TRAPS;
1836
1837 public:
1838 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1839 void do_monitor(ObjectMonitor* mid) {
1840 if (mid->owner() == THREAD) {
1841 if (ObjectMonitor::Knob_VerifyMatch != 0) {
1842 ResourceMark rm;
1843 Handle obj(THREAD, (oop) mid->object());
1844 tty->print("INFO: unexpected locked object:");
1845 javaVFrame::print_locked_object_class_name(tty, obj, "locked");
|