< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page
rev 13349 : imported patch deflate.patch


 948       oop object = (oop)mid->object();
 949       if (object != NULL) {
 950         closure->do_monitor(mid);
 951       }
 952     }
 953     block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
 954   }
 955 }
 956 
 957 // Get the next block in the block list.
 958 static inline ObjectMonitor* next(ObjectMonitor* block) {
 959   assert(block->object() == CHAINMARKER, "must be a valid block header");
 960   block = block->FreeNext;
 961   assert(block == NULL || block->object() == CHAINMARKER, "must be a valid block header");
 962   return block;
 963 }
 964 
 965 
 966 void ObjectSynchronizer::oops_do(OopClosure* f) {
 967   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");




 968   PaddedEnd<ObjectMonitor> * block =
 969     (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
 970   for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
 971     assert(block->object() == CHAINMARKER, "must be a block header");
 972     for (int i = 1; i < _BLOCKSIZE; i++) {
 973       ObjectMonitor* mid = (ObjectMonitor *)&block[i];
 974       if (mid->object() != NULL) {
 975         f->do_oop((oop*)mid->object_addr());
 976       }
 977     }
 978   }
 979 }
 980 
 981 
 982 // -----------------------------------------------------------------------------
 983 // ObjectMonitor Lifecycle
 984 // -----------------------
 985 // Inflation unlinks monitors from the global gFreeList and
 986 // associates them with objects.  Deflation -- which occurs at
 987 // STW-time -- disassociates idle monitors from objects.  Such


1600     assert(mid->object() == NULL, "invariant");
1601 
1602     // Move the object to the working free list defined by freeHeadp, freeTailp
1603     if (*freeHeadp == NULL) *freeHeadp = mid;
1604     if (*freeTailp != NULL) {
1605       ObjectMonitor * prevtail = *freeTailp;
1606       assert(prevtail->FreeNext == NULL, "cleaned up deflated?");
1607       prevtail->FreeNext = mid;
1608     }
1609     *freeTailp = mid;
1610     deflated = true;
1611   }
1612   return deflated;
1613 }
1614 
1615 // Walk a given monitor list, and deflate idle monitors
1616 // The given list could be a per-thread list or a global list
1617 // Caller acquires gListLock
1618 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
1619                                              ObjectMonitor** freeHeadp,
1620                                              ObjectMonitor** freeTailp) {

1621   ObjectMonitor* mid;
1622   ObjectMonitor* next;
1623   ObjectMonitor* cur_mid_in_use = NULL;
1624   int deflated_count = 0;
1625 
1626   for (mid = *listHeadp; mid != NULL;) {
1627     oop obj = (oop) mid->object();
1628     if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
1629       // if deflate_monitor succeeded,
1630       // extract from per-thread in-use list
1631       if (mid == *listHeadp) {
1632         *listHeadp = mid->FreeNext;
1633       } else if (cur_mid_in_use != NULL) {
1634         cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
1635       }
1636       next = mid->FreeNext;
1637       mid->FreeNext = NULL;  // This mid is current tail in the freeHeadp list
1638       mid = next;
1639       deflated_count++;
1640     } else {



1641       cur_mid_in_use = mid;
1642       mid = mid->FreeNext;
1643     }
1644   }
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();
1697 


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");




 948       oop object = (oop)mid->object();
 949       if (object != NULL) {
 950         closure->do_monitor(mid);
 951       }
 952     }
 953     block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
 954   }
 955 }
 956 
 957 // Get the next block in the block list.
 958 static inline ObjectMonitor* next(ObjectMonitor* block) {
 959   assert(block->object() == CHAINMARKER, "must be a valid block header");
 960   block = block->FreeNext;
 961   assert(block == NULL || block->object() == CHAINMARKER, "must be a valid block header");
 962   return block;
 963 }
 964 
 965 
 966 void ObjectSynchronizer::oops_do(OopClosure* f) {
 967   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 968   if (MonitorInUseLists) {
 969     global_used_oops_do(f);
 970     return;
 971   }
 972   PaddedEnd<ObjectMonitor> * block =
 973     (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
 974   for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
 975     assert(block->object() == CHAINMARKER, "must be a block header");
 976     for (int i = 1; i < _BLOCKSIZE; i++) {
 977       ObjectMonitor* mid = (ObjectMonitor *)&block[i];
 978       if (mid->object() != NULL) {
 979         f->do_oop((oop*)mid->object_addr());
 980       }
 981     }
 982   }
 983 }
 984 
 985 
 986 // -----------------------------------------------------------------------------
 987 // ObjectMonitor Lifecycle
 988 // -----------------------
 989 // Inflation unlinks monitors from the global gFreeList and
 990 // associates them with objects.  Deflation -- which occurs at
 991 // STW-time -- disassociates idle monitors from objects.  Such


1604     assert(mid->object() == NULL, "invariant");
1605 
1606     // Move the object to the working free list defined by freeHeadp, freeTailp
1607     if (*freeHeadp == NULL) *freeHeadp = mid;
1608     if (*freeTailp != NULL) {
1609       ObjectMonitor * prevtail = *freeTailp;
1610       assert(prevtail->FreeNext == NULL, "cleaned up deflated?");
1611       prevtail->FreeNext = mid;
1612     }
1613     *freeTailp = mid;
1614     deflated = true;
1615   }
1616   return deflated;
1617 }
1618 
1619 // Walk a given monitor list, and deflate idle monitors
1620 // The given list could be a per-thread list or a global list
1621 // Caller acquires gListLock
1622 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
1623                                              ObjectMonitor** freeHeadp,
1624                                              ObjectMonitor** freeTailp,
1625                                              OopClosure* cl) {
1626   ObjectMonitor* mid;
1627   ObjectMonitor* next;
1628   ObjectMonitor* cur_mid_in_use = NULL;
1629   int deflated_count = 0;
1630 
1631   for (mid = *listHeadp; mid != NULL;) {
1632     oop obj = (oop) mid->object();
1633     if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
1634       // if deflate_monitor succeeded,
1635       // extract from per-thread in-use list
1636       if (mid == *listHeadp) {
1637         *listHeadp = mid->FreeNext;
1638       } else if (cur_mid_in_use != NULL) {
1639         cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
1640       }
1641       next = mid->FreeNext;
1642       mid->FreeNext = NULL;  // This mid is current tail in the freeHeadp list
1643       mid = next;
1644       deflated_count++;
1645     } else {
1646       if (obj != NULL && cl != NULL) {
1647         cl->do_oop((oop*) mid->object_addr());
1648       }
1649       cur_mid_in_use = mid;
1650       mid = mid->FreeNext;
1651     }
1652   }
1653   return deflated_count;
1654 }
1655 
1656 void ObjectSynchronizer::deflate_idle_monitors() {
1657   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1658   int nInuse = 0;              // currently associated with objects
1659   int nInCirculation = 0;      // extant
1660   int nScavenged = 0;          // reclaimed
1661   bool deflated = false;
1662 
1663   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1664   ObjectMonitor * freeTailp = NULL;
1665 
1666   TEVENT(deflate_idle_monitors);
1667   if (MonitorInUseLists) {
1668     if (! Universe::heap()->supports_per_thread_monitor_deflation() ||
1669         ForceMonitorScavenge == 1) {
1670       Universe::heap()->deflate_idle_monitors_all_threads();
1671     }
1672   }
1673 
1674   // Prevent omFlush from changing mids in Thread dtor's during deflation
1675   // And in case the vm thread is acquiring a lock during a safepoint
1676   // See e.g. 6320749
1677   Thread::muxAcquire(&gListLock, "scavenge - return");
1678 
1679   if (MonitorInUseLists) {













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


1733 
1734   // Move the scavenged monitors back to the global free list.
1735   if (freeHeadp != NULL) {
1736     guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1737     assert(freeTailp->FreeNext == NULL, "invariant");
1738     // constant-time list splice - prepend scavenged segment to gFreeList
1739     freeTailp->FreeNext = gFreeList;
1740     gFreeList = freeHeadp;
1741   }
1742   Thread::muxRelease(&gListLock);
1743 
1744   OM_PERFDATA_OP(Deflations, inc(nScavenged));
1745   OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
1746 
1747   // TODO: Add objectMonitor leak detection.
1748   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
1749   GVars.stwRandom = os::random();
1750   GVars.stwCycle++;
1751 }
1752 
1753 void ObjectSynchronizer::deflate_idle_monitors_and_oops_do(Thread* thread, OopClosure* cl) {
1754   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1755   if (! MonitorInUseLists) return;
1756   if (ForceMonitorScavenge == 1) return;
1757   assert(Universe::heap()->supports_per_thread_monitor_deflation(), "only call this when supported by GC");
1758 
1759   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1760   ObjectMonitor * freeTailp = NULL;
1761 
1762   int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp, cl);
1763   thread->omInUseCount-= deflated_count;
1764   if (ObjectMonitor::Knob_VerifyInUse) {
1765     verifyInUse(thread);
1766   }
1767 
1768   // Move the scavenged monitors back to the global free list.
1769   if (freeHeadp != NULL) {
1770     Thread::muxAcquire(&gListLock, "scavenge - return");
1771     guarantee(freeTailp != NULL && deflated_count > 0, "invariant");
1772     assert(freeTailp->FreeNext == NULL, "invariant");
1773 
1774     gMonitorFreeCount += deflated_count;
1775     // constant-time list splice - prepend scavenged segment to gFreeList
1776     freeTailp->FreeNext = gFreeList;
1777     gFreeList = freeHeadp;
1778     Thread::muxRelease(&gListLock);
1779   }
1780 }
1781 
1782 void ObjectSynchronizer::deflate_idle_monitors_all_threads() {
1783   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1784   assert(MonitorInUseLists, "only call this with MonitorInUseLists");
1785 
1786   int nInuse = 0;              // currently associated with objects
1787   int nInCirculation = 0;      // extant
1788   int nScavenged = 0;          // reclaimed
1789 
1790   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
1791   ObjectMonitor * freeTailp = NULL;
1792 
1793   Thread::muxAcquire(&gListLock, "scavenge - return");
1794   for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
1795     nInCirculation+= cur->omInUseCount;
1796     int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
1797     cur->omInUseCount-= deflated_count;
1798     if (ObjectMonitor::Knob_VerifyInUse) {
1799       verifyInUse(cur);
1800     }
1801     nScavenged += deflated_count;
1802     nInuse += cur->omInUseCount;
1803   }
1804 
1805   // Move the scavenged monitors back to the global free list.
1806   if (freeHeadp != NULL) {
1807     guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
1808     assert(freeTailp->FreeNext == NULL, "invariant");
1809 
1810     gMonitorFreeCount += nScavenged;
1811     // constant-time list splice - prepend scavenged segment to gFreeList
1812     freeTailp->FreeNext = gFreeList;
1813     gFreeList = freeHeadp;
1814   }
1815 
1816   gMonitorFreeCount += nScavenged;
1817 
1818   Thread::muxRelease(&gListLock);
1819 }
1820 
1821 // Monitor cleanup on JavaThread::exit
1822 
1823 // Iterate through monitor cache and attempt to release thread's monitors
1824 // Gives up on a particular monitor if an exception occurs, but continues
1825 // the overall iteration, swallowing the exception.
1826 class ReleaseJavaMonitorsClosure: public MonitorClosure {
1827  private:
1828   TRAPS;
1829 
1830  public:
1831   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
1832   void do_monitor(ObjectMonitor* mid) {
1833     if (mid->owner() == THREAD) {
1834       if (ObjectMonitor::Knob_VerifyMatch != 0) {
1835         ResourceMark rm;
1836         Handle obj((oop) mid->object());
1837         tty->print("INFO: unexpected locked object:");
1838         javaVFrame::print_locked_object_class_name(tty, obj, "locked");


< prev index next >