< prev index next >

src/share/vm/runtime/synchronizer.cpp

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


1678   return deflated_count;
1679 }
1680 
1681 void ObjectSynchronizer::deflate_idle_monitors() {
1682   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1683   int nInuse = 0;              // currently associated with objects
1684   int nInCirculation = 0;      // extant
1685   int nScavenged = 0;          // reclaimed
1686   bool deflated = false;
1687 
1688   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1689   ObjectMonitor * freeTailp = NULL;
1690 
1691   TEVENT(deflate_idle_monitors);
1692   // Prevent omFlush from changing mids in Thread dtor's during deflation
1693   // And in case the vm thread is acquiring a lock during a safepoint
1694   // See e.g. 6320749
1695   Thread::muxAcquire(&gListLock, "scavenge - return");
1696 
1697   if (MonitorInUseLists) {
1698     int inUse = 0;
1699     for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
1700       nInCirculation+= cur->omInUseCount;
1701       int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
1702       cur->omInUseCount-= deflated_count;
1703       if (ObjectMonitor::Knob_VerifyInUse) {
1704         verifyInUse(cur);
1705       }
1706       nScavenged += deflated_count;
1707       nInuse += cur->omInUseCount;
1708     }
1709 
1710     // For moribund threads, scan gOmInUseList
1711     if (gOmInUseList) {
1712       nInCirculation += gOmInUseCount;
1713       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1714       gOmInUseCount-= deflated_count;
1715       nScavenged += deflated_count;
1716       nInuse += gOmInUseCount;
1717     }
1718 
1719   } else {
1720     PaddedEnd<ObjectMonitor> * block =
1721       (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1722     for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1723       // Iterate over all extant monitors - Scavenge all idle monitors.
1724       assert(block->object() == CHAINMARKER, "must be a block header");
1725       nInCirculation += _BLOCKSIZE;
1726       for (int i = 1; i < _BLOCKSIZE; i++) {
1727         ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1728         oop obj = (oop)mid->object();


1761 
1762   ForceMonitorScavenge = 0;    // Reset
1763 
1764   // Move the scavenged monitors back to the global free list.
1765   if (freeHeadp != NULL) {
1766     guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1767     assert(freeTailp->FreeNext == NULL, "invariant");
1768     // constant-time list splice - prepend scavenged segment to gFreeList
1769     freeTailp->FreeNext = gFreeList;
1770     gFreeList = freeHeadp;
1771   }
1772   Thread::muxRelease(&gListLock);
1773 
1774   OM_PERFDATA_OP(Deflations, inc(nScavenged));
1775   OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
1776 
1777   // TODO: Add objectMonitor leak detection.
1778   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1779   GVars.stwRandom = os::random();
1780   GVars.stwCycle++;



























1781 }
1782 
1783 // Monitor cleanup on JavaThread::exit
1784 
1785 // Iterate through monitor cache and attempt to release thread's monitors
1786 // Gives up on a particular monitor if an exception occurs, but continues
1787 // the overall iteration, swallowing the exception.
1788 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1789  private:
1790   TRAPS;
1791 
1792  public:
1793   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1794   void do_monitor(ObjectMonitor* mid) {
1795     if (mid->owner() == THREAD) {
1796       if (ObjectMonitor::Knob_VerifyMatch != 0) {
1797         ResourceMark rm;
1798         Handle obj(THREAD, (oop) mid->object());
1799         tty->print("INFO: unexpected locked object:");
1800         javaVFrame::print_locked_object_class_name(tty, obj, "locked");




1678   return deflated_count;
1679 }
1680 
1681 void ObjectSynchronizer::deflate_idle_monitors() {
1682   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1683   int nInuse = 0;              // currently associated with objects
1684   int nInCirculation = 0;      // extant
1685   int nScavenged = 0;          // reclaimed
1686   bool deflated = false;
1687 
1688   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1689   ObjectMonitor * freeTailp = NULL;
1690 
1691   TEVENT(deflate_idle_monitors);
1692   // Prevent omFlush from changing mids in Thread dtor's during deflation
1693   // And in case the vm thread is acquiring a lock during a safepoint
1694   // See e.g. 6320749
1695   Thread::muxAcquire(&gListLock, "scavenge - return");
1696 
1697   if (MonitorInUseLists) {
1698     // Note: the thread-local monitors lists get deflated in
1699     // a separate pass. See deflate_thread_local_monitors().









1700 
1701     // For moribund threads, scan gOmInUseList
1702     if (gOmInUseList) {
1703       nInCirculation += gOmInUseCount;
1704       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1705       gOmInUseCount-= deflated_count;
1706       nScavenged += deflated_count;
1707       nInuse += gOmInUseCount;
1708     }
1709 
1710   } else {
1711     PaddedEnd<ObjectMonitor> * block =
1712       (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1713     for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1714       // Iterate over all extant monitors - Scavenge all idle monitors.
1715       assert(block->object() == CHAINMARKER, "must be a block header");
1716       nInCirculation += _BLOCKSIZE;
1717       for (int i = 1; i < _BLOCKSIZE; i++) {
1718         ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1719         oop obj = (oop)mid->object();


1752 
1753   ForceMonitorScavenge = 0;    // Reset
1754 
1755   // Move the scavenged monitors back to the global free list.
1756   if (freeHeadp != NULL) {
1757     guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1758     assert(freeTailp->FreeNext == NULL, "invariant");
1759     // constant-time list splice - prepend scavenged segment to gFreeList
1760     freeTailp->FreeNext = gFreeList;
1761     gFreeList = freeHeadp;
1762   }
1763   Thread::muxRelease(&gListLock);
1764 
1765   OM_PERFDATA_OP(Deflations, inc(nScavenged));
1766   OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
1767 
1768   // TODO: Add objectMonitor leak detection.
1769   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1770   GVars.stwRandom = os::random();
1771   GVars.stwCycle++;
1772 }
1773 
1774 void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread) {
1775   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1776   if (! MonitorInUseLists) return;
1777 
1778   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1779   ObjectMonitor * freeTailp = NULL;
1780 
1781   int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
1782   thread->omInUseCount-= deflated_count;
1783   if (ObjectMonitor::Knob_VerifyInUse) {
1784     verifyInUse(thread);
1785   }
1786 
1787   // Move the scavenged monitors back to the global free list.
1788   if (freeHeadp != NULL) {
1789     Thread::muxAcquire(&gListLock, "scavenge - return");
1790     guarantee(freeTailp != NULL && deflated_count > 0, "invariant");
1791     assert(freeTailp->FreeNext == NULL, "invariant");
1792 
1793     gMonitorFreeCount += deflated_count;
1794     // constant-time list splice - prepend scavenged segment to gFreeList
1795     freeTailp->FreeNext = gFreeList;
1796     gFreeList = freeHeadp;
1797     Thread::muxRelease(&gListLock);
1798   }
1799 }
1800 
1801 // Monitor cleanup on JavaThread::exit
1802 
1803 // Iterate through monitor cache and attempt to release thread's monitors
1804 // Gives up on a particular monitor if an exception occurs, but continues
1805 // the overall iteration, swallowing the exception.
1806 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1807  private:
1808   TRAPS;
1809 
1810  public:
1811   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1812   void do_monitor(ObjectMonitor* mid) {
1813     if (mid->owner() == THREAD) {
1814       if (ObjectMonitor::Knob_VerifyMatch != 0) {
1815         ResourceMark rm;
1816         Handle obj(THREAD, (oop) mid->object());
1817         tty->print("INFO: unexpected locked object:");
1818         javaVFrame::print_locked_object_class_name(tty, obj, "locked");


< prev index next >