< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page
rev 13343 : Deflate idle monitors per thread.


1645   return deflated_count;
1646 }
1647 
1648 void ObjectSynchronizer::deflate_idle_monitors() {
1649   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1650   int nInuse = 0;              // currently associated with objects
1651   int nInCirculation = 0;      // extant
1652   int nScavenged = 0;          // reclaimed
1653   bool deflated = false;
1654 
1655   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1656   ObjectMonitor * freeTailp = NULL;
1657 
1658   TEVENT(deflate_idle_monitors);
1659   // Prevent omFlush from changing mids in Thread dtor's during deflation
1660   // And in case the vm thread is acquiring a lock during a safepoint
1661   // See e.g. 6320749
1662   Thread::muxAcquire(&gListLock, "scavenge - return");
1663 
1664   if (MonitorInUseLists) {
1665     int inUse = 0;
1666     for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
1667       nInCirculation+= cur->omInUseCount;
1668       int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
1669       cur->omInUseCount-= deflated_count;
1670       if (ObjectMonitor::Knob_VerifyInUse) {
1671         verifyInUse(cur);
1672       }
1673       nScavenged += deflated_count;
1674       nInuse += cur->omInUseCount;
1675     }

1676 
1677     // For moribund threads, scan gOmInUseList
1678     if (gOmInUseList) {
1679       nInCirculation += gOmInUseCount;
1680       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1681       gOmInUseCount-= deflated_count;
1682       nScavenged += deflated_count;
1683       nInuse += gOmInUseCount;
1684     }
1685 
1686   } else {
1687     PaddedEnd<ObjectMonitor> * block =
1688       (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1689     for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1690       // Iterate over all extant monitors - Scavenge all idle monitors.
1691       assert(block->object() == CHAINMARKER, "must be a block header");
1692       nInCirculation += _BLOCKSIZE;
1693       for (int i = 1; i < _BLOCKSIZE; i++) {
1694         ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1695         oop obj = (oop)mid->object();


1728 
1729   ForceMonitorScavenge = 0;    // Reset
1730 
1731   // Move the scavenged monitors back to the global free list.
1732   if (freeHeadp != NULL) {
1733     guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1734     assert(freeTailp->FreeNext == NULL, "invariant");
1735     // constant-time list splice - prepend scavenged segment to gFreeList
1736     freeTailp->FreeNext = gFreeList;
1737     gFreeList = freeHeadp;
1738   }
1739   Thread::muxRelease(&gListLock);
1740 
1741   OM_PERFDATA_OP(Deflations, inc(nScavenged));
1742   OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
1743 
1744   // TODO: Add objectMonitor leak detection.
1745   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1746   GVars.stwRandom = os::random();
1747   GVars.stwCycle++;




























1748 }
1749 
1750 // Monitor cleanup on JavaThread::exit
1751 
1752 // Iterate through monitor cache and attempt to release thread's monitors
1753 // Gives up on a particular monitor if an exception occurs, but continues
1754 // the overall iteration, swallowing the exception.
1755 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1756  private:
1757   TRAPS;
1758 
1759  public:
1760   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1761   void do_monitor(ObjectMonitor* mid) {
1762     if (mid->owner() == THREAD) {
1763       if (ObjectMonitor::Knob_VerifyMatch != 0) {
1764         ResourceMark rm;
1765         Handle obj((oop) mid->object());
1766         tty->print("INFO: unexpected locked object:");
1767         javaVFrame::print_locked_object_class_name(tty, obj, "locked");




1645   return deflated_count;
1646 }
1647 
1648 void ObjectSynchronizer::deflate_idle_monitors() {
1649   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1650   int nInuse = 0;              // currently associated with objects
1651   int nInCirculation = 0;      // extant
1652   int nScavenged = 0;          // reclaimed
1653   bool deflated = false;
1654 
1655   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1656   ObjectMonitor * freeTailp = NULL;
1657 
1658   TEVENT(deflate_idle_monitors);
1659   // Prevent omFlush from changing mids in Thread dtor's during deflation
1660   // And in case the vm thread is acquiring a lock during a safepoint
1661   // See e.g. 6320749
1662   Thread::muxAcquire(&gListLock, "scavenge - return");
1663 
1664   if (MonitorInUseLists) {
1665     if (! DeflateIdleMonitorsPerThread) {
1666       for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
1667         nInCirculation+= cur->omInUseCount;
1668         int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
1669         cur->omInUseCount-= deflated_count;
1670         if (ObjectMonitor::Knob_VerifyInUse) {
1671           verifyInUse(cur);
1672         }
1673         nScavenged += deflated_count;
1674         nInuse += cur->omInUseCount;
1675       }
1676     }
1677 
1678     // For moribund threads, scan gOmInUseList
1679     if (gOmInUseList) {
1680       nInCirculation += gOmInUseCount;
1681       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
1682       gOmInUseCount-= deflated_count;
1683       nScavenged += deflated_count;
1684       nInuse += gOmInUseCount;
1685     }
1686 
1687   } else {
1688     PaddedEnd<ObjectMonitor> * block =
1689       (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
1690     for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
1691       // Iterate over all extant monitors - Scavenge all idle monitors.
1692       assert(block->object() == CHAINMARKER, "must be a block header");
1693       nInCirculation += _BLOCKSIZE;
1694       for (int i = 1; i < _BLOCKSIZE; i++) {
1695         ObjectMonitor* mid = (ObjectMonitor*)&block[i];
1696         oop obj = (oop)mid->object();


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


< prev index next >