< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page
rev 13206 : 8180932: Parallelize safepoint cleanup
Summary: Provide infrastructure to do safepoint cleanup tasks using parallel worker threads
Reviewed-by: dholmes, rehn, dcubed, thartmann


1644     obj->release_set_mark(mid->header());
1645     mid->clear();
1646 
1647     assert(mid->object() == NULL, "invariant");
1648 
1649     // Move the object to the working free list defined by freeHeadp, freeTailp
1650     if (*freeHeadp == NULL) *freeHeadp = mid;
1651     if (*freeTailp != NULL) {
1652       ObjectMonitor * prevtail = *freeTailp;
1653       assert(prevtail->FreeNext == NULL, "cleaned up deflated?");
1654       prevtail->FreeNext = mid;
1655     }
1656     *freeTailp = mid;
1657     deflated = true;
1658   }
1659   return deflated;
1660 }
1661 
1662 // Walk a given monitor list, and deflate idle monitors
1663 // The given list could be a per-thread list or a global list
1664 // Caller acquires gListLock










1665 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
1666                                              ObjectMonitor** freeHeadp,
1667                                              ObjectMonitor** freeTailp) {
1668   ObjectMonitor* mid;
1669   ObjectMonitor* next;
1670   ObjectMonitor* cur_mid_in_use = NULL;
1671   int deflated_count = 0;
1672 
1673   for (mid = *listHeadp; mid != NULL;) {
1674     oop obj = (oop) mid->object();
1675     if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
1676       // if deflate_monitor succeeded,
1677       // extract from per-thread in-use list
1678       if (mid == *listHeadp) {
1679         *listHeadp = mid->FreeNext;
1680       } else if (cur_mid_in_use != NULL) {
1681         cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
1682       }
1683       next = mid->FreeNext;
1684       mid->FreeNext = NULL;  // This mid is current tail in the freeHeadp list
1685       mid = next;
1686       deflated_count++;
1687     } else {
1688       cur_mid_in_use = mid;
1689       mid = mid->FreeNext;
1690     }
1691   }
1692   return deflated_count;
1693 }
1694 
1695 void ObjectSynchronizer::deflate_idle_monitors() {






1696   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;
1701 
1702   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1703   ObjectMonitor * freeTailp = NULL;
1704 
1705   TEVENT(deflate_idle_monitors);
1706   // Prevent omFlush from changing mids in Thread dtor's during deflation
1707   // And in case the vm thread is acquiring a lock during a safepoint
1708   // See e.g. 6320749
1709   Thread::muxAcquire(&gListLock, "scavenge - return");
1710 
1711   if (MonitorInUseLists) {
1712     int inUse = 0;
1713     for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
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 
1724     // For moribund threads, scan gOmInUseList
1725     if (gOmInUseList) {
1726       nInCirculation += gOmInUseCount;
1727       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1728       gOmInUseCount-= deflated_count;
1729       nScavenged += deflated_count;
1730       nInuse += gOmInUseCount;
1731     }
1732 
1733   } else {
1734     PaddedEnd<ObjectMonitor> * block =
1735       (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1736     for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1737       // Iterate over all extant monitors - Scavenge all idle monitors.
1738       assert(block->object() == CHAINMARKER, "must be a block header");
1739       nInCirculation += _BLOCKSIZE;
1740       for (int i = 1; i < _BLOCKSIZE; i++) {
1741         ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1742         oop obj = (oop)mid->object();
1743 
1744         if (obj == NULL) {
1745           // The monitor is not associated with an object.
1746           // The monitor should either be a thread-specific private
1747           // free list or the global free list.
1748           // obj == NULL IMPLIES mid->is_busy() == 0
1749           guarantee(!mid->is_busy(), "invariant");
1750           continue;
1751         }
1752         deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
1753 
1754         if (deflated) {
1755           mid->FreeNext = NULL;
1756           nScavenged++;
1757         } else {
1758           nInuse++;
1759         }
1760       }
1761     }
1762   }
1763 
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.
1779   if (freeHeadp != NULL) {
1780     guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1781     assert(freeTailp->FreeNext == NULL, "invariant");

1782     // constant-time list splice - prepend scavenged segment to gFreeList
1783     freeTailp->FreeNext = gFreeList;
1784     gFreeList = freeHeadp;
1785   }
1786   Thread::muxRelease(&gListLock);
1787 
1788   OM_PERFDATA_OP(Deflations, inc(nScavenged));
1789   OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
1790 
1791   // TODO: Add objectMonitor leak detection.
1792   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1793   GVars.stwRandom = os::random();
1794   GVars.stwCycle++;
1795 }
1796 
1797 // Monitor cleanup on JavaThread::exit
1798 
1799 // Iterate through monitor cache and attempt to release thread's monitors
1800 // Gives up on a particular monitor if an exception occurs, but continues
1801 // the overall iteration, swallowing the exception.
1802 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1803  private:
1804   TRAPS;
1805 
1806  public:
1807   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1808   void do_monitor(ObjectMonitor* mid) {
1809     if (mid->owner() == THREAD) {
1810       if (ObjectMonitor::Knob_VerifyMatch != 0) {
1811         ResourceMark rm;
1812         Handle obj(THREAD, (oop) mid->object());
1813         tty->print("INFO: unexpected locked object:");
1814         javaVFrame::print_locked_object_class_name(tty, obj, "locked");




1644     obj->release_set_mark(mid->header());
1645     mid->clear();
1646 
1647     assert(mid->object() == NULL, "invariant");
1648 
1649     // Move the object to the working free list defined by freeHeadp, freeTailp
1650     if (*freeHeadp == NULL) *freeHeadp = mid;
1651     if (*freeTailp != NULL) {
1652       ObjectMonitor * prevtail = *freeTailp;
1653       assert(prevtail->FreeNext == NULL, "cleaned up deflated?");
1654       prevtail->FreeNext = mid;
1655     }
1656     *freeTailp = mid;
1657     deflated = true;
1658   }
1659   return deflated;
1660 }
1661 
1662 // Walk a given monitor list, and deflate idle monitors
1663 // The given list could be a per-thread list or a global list
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.
1675 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
1676                                              ObjectMonitor** freeHeadp,
1677                                              ObjectMonitor** freeTailp) {
1678   ObjectMonitor* mid;
1679   ObjectMonitor* next;
1680   ObjectMonitor* cur_mid_in_use = NULL;
1681   int deflated_count = 0;
1682 
1683   for (mid = *listHeadp; mid != NULL;) {
1684     oop obj = (oop) mid->object();
1685     if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
1686       // if deflate_monitor succeeded,
1687       // extract from per-thread in-use list
1688       if (mid == *listHeadp) {
1689         *listHeadp = mid->FreeNext;
1690       } else if (cur_mid_in_use != NULL) {
1691         cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
1692       }
1693       next = mid->FreeNext;
1694       mid->FreeNext = NULL;  // This mid is current tail in the freeHeadp list
1695       mid = next;
1696       deflated_count++;
1697     } else {
1698       cur_mid_in_use = mid;
1699       mid = mid->FreeNext;
1700     }
1701   }
1702   return deflated_count;
1703 }
1704 
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) {
1712   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");



1713   bool deflated = false;
1714 
1715   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1716   ObjectMonitor * freeTailp = NULL;
1717 
1718   TEVENT(deflate_idle_monitors);
1719   // Prevent omFlush from changing mids in Thread dtor's during deflation
1720   // And in case the vm thread is acquiring a lock during a safepoint
1721   // See e.g. 6320749
1722   Thread::muxAcquire(&gListLock, "scavenge - return");
1723 
1724   if (MonitorInUseLists) {
1725     // Note: the thread-local monitors lists get deflated in
1726     // a separate pass. See deflate_thread_local_monitors().









1727 
1728     // For moribund threads, scan gOmInUseList
1729     if (gOmInUseList) {
1730       counters->nInCirculation += gOmInUseCount;
1731       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1732       gOmInUseCount -= deflated_count;
1733       counters->nScavenged += deflated_count;
1734       counters->nInuse += gOmInUseCount;
1735     }
1736 
1737   } else {
1738     PaddedEnd<ObjectMonitor> * block =
1739       (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1740     for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1741       // Iterate over all extant monitors - Scavenge all idle monitors.
1742       assert(block->object() == CHAINMARKER, "must be a block header");
1743       counters->nInCirculation += _BLOCKSIZE;
1744       for (int i = 1; i < _BLOCKSIZE; i++) {
1745         ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1746         oop obj = (oop)mid->object();
1747 
1748         if (obj == NULL) {
1749           // The monitor is not associated with an object.
1750           // The monitor should either be a thread-specific private
1751           // free list or the global free list.
1752           // obj == NULL IMPLIES mid->is_busy() == 0
1753           guarantee(!mid->is_busy(), "invariant");
1754           continue;
1755         }
1756         deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
1757 
1758         if (deflated) {
1759           mid->FreeNext = NULL;
1760           counters->nScavenged++;
1761         } else {
1762           counters->nInuse++;
1763         }
1764       }
1765     }
1766   }
1767 
1768   // Move the scavenged monitors back to the global free list.
1769   if (freeHeadp != NULL) {
1770     guarantee(freeTailp != NULL && counters->nScavenged > 0, "invariant");
1771     assert(freeTailp->FreeNext == NULL, "invariant");
1772     // constant-time list splice - prepend scavenged segment to gFreeList
1773     freeTailp->FreeNext = gFreeList;
1774     gFreeList = freeHeadp;
1775   }
1776   Thread::muxRelease(&gListLock);
1777 
1778 }
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));
1797 
1798   // TODO: Add objectMonitor leak detection.
1799   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1800   GVars.stwRandom = os::random();
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);








1834 }
1835 
1836 // Monitor cleanup on JavaThread::exit
1837 
1838 // Iterate through monitor cache and attempt to release thread's monitors
1839 // Gives up on a particular monitor if an exception occurs, but continues
1840 // the overall iteration, swallowing the exception.
1841 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1842  private:
1843   TRAPS;
1844 
1845  public:
1846   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1847   void do_monitor(ObjectMonitor* mid) {
1848     if (mid->owner() == THREAD) {
1849       if (ObjectMonitor::Knob_VerifyMatch != 0) {
1850         ResourceMark rm;
1851         Handle obj(THREAD, (oop) mid->object());
1852         tty->print("INFO: unexpected locked object:");
1853         javaVFrame::print_locked_object_class_name(tty, obj, "locked");


< prev index next >