comparison src/share/vm/runtime/synchronizer.cpp @ 1587:b96a3e44582f

6852873: Reduce safepoint cleanup time Summary: New optional flags to reduce inflated monitor cleanup times Reviewed-by: chrisphi, dice
author acorn
date Thu, 03 Jun 2010 13:21:47 -0400
parents b9fba36710f2
children 3a9de63b2209
comparison
equal deleted inserted replaced
1561:3548f3198dca 1587:b96a3e44582f
183 volatile int hcSequence ; 183 volatile int hcSequence ;
184 double padFinal [8] ; 184 double padFinal [8] ;
185 } ; 185 } ;
186 186
187 static SharedGlobals GVars ; 187 static SharedGlobals GVars ;
188 static int MonitorScavengeThreshold = 1000000 ;
189 static volatile int ForceMonitorScavenge = 0 ; // Scavenge required and pending
188 190
189 191
190 // Tunables ... 192 // Tunables ...
191 // The knob* variables are effectively final. Once set they should 193 // The knob* variables are effectively final. Once set they should
192 // never be modified hence. Consider using __read_mostly with GCC. 194 // never be modified hence. Consider using __read_mostly with GCC.
744 // 746 //
745 747
746 ObjectMonitor * ObjectSynchronizer::gBlockList = NULL ; 748 ObjectMonitor * ObjectSynchronizer::gBlockList = NULL ;
747 ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL ; 749 ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL ;
748 static volatile intptr_t ListLock = 0 ; // protects global monitor free-list cache 750 static volatile intptr_t ListLock = 0 ; // protects global monitor free-list cache
751 static volatile int MonitorFreeCount = 0 ; // # on gFreeList
752 static volatile int MonitorPopulation = 0 ; // # Extant -- in circulation
749 #define CHAINMARKER ((oop)-1) 753 #define CHAINMARKER ((oop)-1)
754
755 // Constraining monitor pool growth via MonitorBound ...
756 //
757 // The monitor pool is grow-only. We scavenge at STW safepoint-time, but the
758 // the rate of scavenging is driven primarily by GC. As such, we can find
759 // an inordinate number of monitors in circulation.
760 // To avoid that scenario we can artificially induce a STW safepoint
761 // if the pool appears to be growing past some reasonable bound.
762 // Generally we favor time in space-time tradeoffs, but as there's no
763 // natural back-pressure on the # of extant monitors we need to impose some
764 // type of limit. Beware that if MonitorBound is set to too low a value
765 // we could just loop. In addition, if MonitorBound is set to a low value
766 // we'll incur more safepoints, which are harmful to performance.
767 // See also: GuaranteedSafepointInterval
768 //
769 // As noted elsewhere, the correct long-term solution is to deflate at
770 // monitorexit-time, in which case the number of inflated objects is bounded
771 // by the number of threads. That policy obviates the need for scavenging at
772 // STW safepoint time. As an aside, scavenging can be time-consuming when the
773 // # of extant monitors is large. Unfortunately there's a day-1 assumption baked
774 // into much HotSpot code that the object::monitor relationship, once established
775 // or observed, will remain stable except over potential safepoints.
776 //
777 // We can use either a blocking synchronous VM operation or an async VM operation.
778 // -- If we use a blocking VM operation :
779 // Calls to ScavengeCheck() should be inserted only into 'safe' locations in paths
780 // that lead to ::inflate() or ::omAlloc().
781 // Even though the safepoint will not directly induce GC, a GC might
782 // piggyback on the safepoint operation, so the caller should hold no naked oops.
783 // Furthermore, monitor::object relationships are NOT necessarily stable over this call
784 // unless the caller has made provisions to "pin" the object to the monitor, say
785 // by incrementing the monitor's _count field.
786 // -- If we use a non-blocking asynchronous VM operation :
787 // the constraints above don't apply. The safepoint will fire in the future
788 // at a more convenient time. On the other hand the latency between posting and
789 // running the safepoint introduces or admits "slop" or laxity during which the
790 // monitor population can climb further above the threshold. The monitor population,
791 // however, tends to converge asymptotically over time to a count that's slightly
792 // above the target value specified by MonitorBound. That is, we avoid unbounded
793 // growth, albeit with some imprecision.
794 //
795 // The current implementation uses asynchronous VM operations.
796 //
797 // Ideally we'd check if (MonitorPopulation > MonitorBound) in omAlloc()
798 // immediately before trying to grow the global list via allocation.
799 // If the predicate was true then we'd induce a synchronous safepoint, wait
800 // for the safepoint to complete, and then again to allocate from the global
801 // free list. This approach is much simpler and precise, admitting no "slop".
802 // Unfortunately we can't safely safepoint in the midst of omAlloc(), so
803 // instead we use asynchronous safepoints.
804
805 static void InduceScavenge (Thread * Self, const char * Whence) {
806 // Induce STW safepoint to trim monitors
807 // Ultimately, this results in a call to deflate_idle_monitors() in the near future.
808 // More precisely, trigger an asynchronous STW safepoint as the number
809 // of active monitors passes the specified threshold.
810 // TODO: assert thread state is reasonable
811
812 if (ForceMonitorScavenge == 0 && Atomic::xchg (1, &ForceMonitorScavenge) == 0) {
813 if (Knob_Verbose) {
814 ::printf ("Monitor scavenge - Induced STW @%s (%d)\n", Whence, ForceMonitorScavenge) ;
815 ::fflush(stdout) ;
816 }
817 // Induce a 'null' safepoint to scavenge monitors
818 // Must VM_Operation instance be heap allocated as the op will be enqueue and posted
819 // to the VMthread and have a lifespan longer than that of this activation record.
820 // The VMThread will delete the op when completed.
821 VMThread::execute (new VM_ForceAsyncSafepoint()) ;
822
823 if (Knob_Verbose) {
824 ::printf ("Monitor scavenge - STW posted @%s (%d)\n", Whence, ForceMonitorScavenge) ;
825 ::fflush(stdout) ;
826 }
827 }
828 }
750 829
751 ObjectMonitor * ATTR ObjectSynchronizer::omAlloc (Thread * Self) { 830 ObjectMonitor * ATTR ObjectSynchronizer::omAlloc (Thread * Self) {
752 // A large MAXPRIVATE value reduces both list lock contention 831 // A large MAXPRIVATE value reduces both list lock contention
753 // and list coherency traffic, but also tends to increase the 832 // and list coherency traffic, but also tends to increase the
754 // number of objectMonitors in circulation as well as the STW 833 // number of objectMonitors in circulation as well as the STW
768 if (m != NULL) { 847 if (m != NULL) {
769 Self->omFreeList = m->FreeNext ; 848 Self->omFreeList = m->FreeNext ;
770 Self->omFreeCount -- ; 849 Self->omFreeCount -- ;
771 // CONSIDER: set m->FreeNext = BAD -- diagnostic hygiene 850 // CONSIDER: set m->FreeNext = BAD -- diagnostic hygiene
772 guarantee (m->object() == NULL, "invariant") ; 851 guarantee (m->object() == NULL, "invariant") ;
852 if (MonitorInUseLists) {
853 m->FreeNext = Self->omInUseList;
854 Self->omInUseList = m;
855 Self->omInUseCount ++;
856 }
773 return m ; 857 return m ;
774 } 858 }
775 859
776 // 2: try to allocate from the global gFreeList 860 // 2: try to allocate from the global gFreeList
777 // CONSIDER: use muxTry() instead of muxAcquire(). 861 // CONSIDER: use muxTry() instead of muxAcquire().
782 // Reprovision the thread's omFreeList. 866 // Reprovision the thread's omFreeList.
783 // Use bulk transfers to reduce the allocation rate and heat 867 // Use bulk transfers to reduce the allocation rate and heat
784 // on various locks. 868 // on various locks.
785 Thread::muxAcquire (&ListLock, "omAlloc") ; 869 Thread::muxAcquire (&ListLock, "omAlloc") ;
786 for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL; ) { 870 for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL; ) {
871 MonitorFreeCount --;
787 ObjectMonitor * take = gFreeList ; 872 ObjectMonitor * take = gFreeList ;
788 gFreeList = take->FreeNext ; 873 gFreeList = take->FreeNext ;
789 guarantee (take->object() == NULL, "invariant") ; 874 guarantee (take->object() == NULL, "invariant") ;
790 guarantee (!take->is_busy(), "invariant") ; 875 guarantee (!take->is_busy(), "invariant") ;
791 take->Recycle() ; 876 take->Recycle() ;
794 Thread::muxRelease (&ListLock) ; 879 Thread::muxRelease (&ListLock) ;
795 Self->omFreeProvision += 1 + (Self->omFreeProvision/2) ; 880 Self->omFreeProvision += 1 + (Self->omFreeProvision/2) ;
796 if (Self->omFreeProvision > MAXPRIVATE ) Self->omFreeProvision = MAXPRIVATE ; 881 if (Self->omFreeProvision > MAXPRIVATE ) Self->omFreeProvision = MAXPRIVATE ;
797 TEVENT (omFirst - reprovision) ; 882 TEVENT (omFirst - reprovision) ;
798 continue ; 883 continue ;
884
885 const int mx = MonitorBound ;
886 if (mx > 0 && (MonitorPopulation-MonitorFreeCount) > mx) {
887 // We can't safely induce a STW safepoint from omAlloc() as our thread
888 // state may not be appropriate for such activities and callers may hold
889 // naked oops, so instead we defer the action.
890 InduceScavenge (Self, "omAlloc") ;
891 }
892 continue;
799 } 893 }
800 894
801 // 3: allocate a block of new ObjectMonitors 895 // 3: allocate a block of new ObjectMonitors
802 // Both the local and global free lists are empty -- resort to malloc(). 896 // Both the local and global free lists are empty -- resort to malloc().
803 // In the current implementation objectMonitors are TSM - immortal. 897 // In the current implementation objectMonitors are TSM - immortal.
834 // list activity. 928 // list activity.
835 929
836 // Acquire the ListLock to manipulate BlockList and FreeList. 930 // Acquire the ListLock to manipulate BlockList and FreeList.
837 // An Oyama-Taura-Yonezawa scheme might be more efficient. 931 // An Oyama-Taura-Yonezawa scheme might be more efficient.
838 Thread::muxAcquire (&ListLock, "omAlloc [2]") ; 932 Thread::muxAcquire (&ListLock, "omAlloc [2]") ;
933 MonitorPopulation += _BLOCKSIZE-1;
934 MonitorFreeCount += _BLOCKSIZE-1;
839 935
840 // Add the new block to the list of extant blocks (gBlockList). 936 // Add the new block to the list of extant blocks (gBlockList).
841 // The very first objectMonitor in a block is reserved and dedicated. 937 // The very first objectMonitor in a block is reserved and dedicated.
842 // It serves as blocklist "next" linkage. 938 // It serves as blocklist "next" linkage.
843 temp[0].FreeNext = gBlockList; 939 temp[0].FreeNext = gBlockList;
892 ObjectMonitor * List = Self->omFreeList ; // Null-terminated SLL 988 ObjectMonitor * List = Self->omFreeList ; // Null-terminated SLL
893 Self->omFreeList = NULL ; 989 Self->omFreeList = NULL ;
894 if (List == NULL) return ; 990 if (List == NULL) return ;
895 ObjectMonitor * Tail = NULL ; 991 ObjectMonitor * Tail = NULL ;
896 ObjectMonitor * s ; 992 ObjectMonitor * s ;
993 int Tally = 0;
897 for (s = List ; s != NULL ; s = s->FreeNext) { 994 for (s = List ; s != NULL ; s = s->FreeNext) {
995 Tally ++ ;
898 Tail = s ; 996 Tail = s ;
899 guarantee (s->object() == NULL, "invariant") ; 997 guarantee (s->object() == NULL, "invariant") ;
900 guarantee (!s->is_busy(), "invariant") ; 998 guarantee (!s->is_busy(), "invariant") ;
901 s->set_owner (NULL) ; // redundant but good hygiene 999 s->set_owner (NULL) ; // redundant but good hygiene
902 TEVENT (omFlush - Move one) ; 1000 TEVENT (omFlush - Move one) ;
904 1002
905 guarantee (Tail != NULL && List != NULL, "invariant") ; 1003 guarantee (Tail != NULL && List != NULL, "invariant") ;
906 Thread::muxAcquire (&ListLock, "omFlush") ; 1004 Thread::muxAcquire (&ListLock, "omFlush") ;
907 Tail->FreeNext = gFreeList ; 1005 Tail->FreeNext = gFreeList ;
908 gFreeList = List ; 1006 gFreeList = List ;
1007 MonitorFreeCount += Tally;
909 Thread::muxRelease (&ListLock) ; 1008 Thread::muxRelease (&ListLock) ;
910 TEVENT (omFlush) ; 1009 TEVENT (omFlush) ;
911 } 1010 }
912 1011
913 1012
1745 // 1844 //
1746 // Beware that we scavenge at *every* stop-the-world point. 1845 // Beware that we scavenge at *every* stop-the-world point.
1747 // Having a large number of monitors in-circulation negatively 1846 // Having a large number of monitors in-circulation negatively
1748 // impacts the performance of some applications (e.g., PointBase). 1847 // impacts the performance of some applications (e.g., PointBase).
1749 // Broadly, we want to minimize the # of monitors in circulation. 1848 // Broadly, we want to minimize the # of monitors in circulation.
1750 // Alternately, we could partition the active monitors into sub-lists 1849 //
1751 // of those that need scanning and those that do not. 1850 // We have added a flag, MonitorInUseLists, which creates a list
1752 // Specifically, we would add a new sub-list of objectmonitors 1851 // of active monitors for each thread. deflate_idle_monitors()
1753 // that are in-circulation and potentially active. deflate_idle_monitors() 1852 // only scans the per-thread inuse lists. omAlloc() puts all
1754 // would scan only that list. Other monitors could reside on a quiescent 1853 // assigned monitors on the per-thread list. deflate_idle_monitors()
1755 // list. Such sequestered monitors wouldn't need to be scanned by 1854 // returns the non-busy monitors to the global free list.
1756 // deflate_idle_monitors(). omAlloc() would first check the global free list, 1855 // An alternative could have used a single global inuse list. The
1757 // then the quiescent list, and, failing those, would allocate a new block. 1856 // downside would have been the additional cost of acquiring the global list lock
1758 // Deflate_idle_monitors() would scavenge and move monitors to the 1857 // for every omAlloc().
1759 // quiescent list.
1760 // 1858 //
1761 // Perversely, the heap size -- and thus the STW safepoint rate -- 1859 // Perversely, the heap size -- and thus the STW safepoint rate --
1762 // typically drives the scavenge rate. Large heaps can mean infrequent GC, 1860 // typically drives the scavenge rate. Large heaps can mean infrequent GC,
1763 // which in turn can mean large(r) numbers of objectmonitors in circulation. 1861 // which in turn can mean large(r) numbers of objectmonitors in circulation.
1764 // This is an unfortunate aspect of this design. 1862 // This is an unfortunate aspect of this design.
1766 // Another refinement would be to refrain from calling deflate_idle_monitors() 1864 // Another refinement would be to refrain from calling deflate_idle_monitors()
1767 // except at stop-the-world points associated with garbage collections. 1865 // except at stop-the-world points associated with garbage collections.
1768 // 1866 //
1769 // An even better solution would be to deflate on-the-fly, aggressively, 1867 // An even better solution would be to deflate on-the-fly, aggressively,
1770 // at monitorexit-time as is done in EVM's metalock or Relaxed Locks. 1868 // at monitorexit-time as is done in EVM's metalock or Relaxed Locks.
1869
1870
1871 // Deflate a single monitor if not in use
1872 // Return true if deflated, false if in use
1873 bool ObjectSynchronizer::deflate_monitor(ObjectMonitor* mid, oop obj,
1874 ObjectMonitor** FreeHeadp, ObjectMonitor** FreeTailp) {
1875 bool deflated;
1876 // Normal case ... The monitor is associated with obj.
1877 guarantee (obj->mark() == markOopDesc::encode(mid), "invariant") ;
1878 guarantee (mid == obj->mark()->monitor(), "invariant");
1879 guarantee (mid->header()->is_neutral(), "invariant");
1880
1881 if (mid->is_busy()) {
1882 if (ClearResponsibleAtSTW) mid->_Responsible = NULL ;
1883 deflated = false;
1884 } else {
1885 // Deflate the monitor if it is no longer being used
1886 // It's idle - scavenge and return to the global free list
1887 // plain old deflation ...
1888 TEVENT (deflate_idle_monitors - scavenge1) ;
1889 if (TraceMonitorInflation) {
1890 if (obj->is_instance()) {
1891 ResourceMark rm;
1892 tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
1893 (intptr_t) obj, (intptr_t) obj->mark(), Klass::cast(obj->klass())->external_name());
1894 }
1895 }
1896
1897 // Restore the header back to obj
1898 obj->release_set_mark(mid->header());
1899 mid->clear();
1900
1901 assert (mid->object() == NULL, "invariant") ;
1902
1903 // Move the object to the working free list defined by FreeHead,FreeTail.
1904 if (*FreeHeadp == NULL) *FreeHeadp = mid;
1905 if (*FreeTailp != NULL) {
1906 ObjectMonitor * prevtail = *FreeTailp;
1907 prevtail->FreeNext = mid;
1908 }
1909 *FreeTailp = mid;
1910 deflated = true;
1911 }
1912 return deflated;
1913 }
1771 1914
1772 void ObjectSynchronizer::deflate_idle_monitors() { 1915 void ObjectSynchronizer::deflate_idle_monitors() {
1773 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1916 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
1774 int nInuse = 0 ; // currently associated with objects 1917 int nInuse = 0 ; // currently associated with objects
1775 int nInCirculation = 0 ; // extant 1918 int nInCirculation = 0 ; // extant
1776 int nScavenged = 0 ; // reclaimed 1919 int nScavenged = 0 ; // reclaimed
1920 bool deflated = false;
1777 1921
1778 ObjectMonitor * FreeHead = NULL ; // Local SLL of scavenged monitors 1922 ObjectMonitor * FreeHead = NULL ; // Local SLL of scavenged monitors
1779 ObjectMonitor * FreeTail = NULL ; 1923 ObjectMonitor * FreeTail = NULL ;
1780 1924
1925 TEVENT (deflate_idle_monitors) ;
1926 // Prevent omFlush from changing mids in Thread dtor's during deflation
1927 // And in case the vm thread is acquiring a lock during a safepoint
1928 // See e.g. 6320749
1929 Thread::muxAcquire (&ListLock, "scavenge - return") ;
1930
1931 if (MonitorInUseLists) {
1932 ObjectMonitor* mid;
1933 ObjectMonitor* next;
1934 ObjectMonitor* curmidinuse;
1935 for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
1936 curmidinuse = NULL;
1937 for (mid = cur->omInUseList; mid != NULL; ) {
1938 oop obj = (oop) mid->object();
1939 deflated = false;
1940 if (obj != NULL) {
1941 deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail);
1942 }
1943 if (deflated) {
1944 // extract from per-thread in-use-list
1945 if (mid == cur->omInUseList) {
1946 cur->omInUseList = mid->FreeNext;
1947 } else if (curmidinuse != NULL) {
1948 curmidinuse->FreeNext = mid->FreeNext; // maintain the current thread inuselist
1949 }
1950 next = mid->FreeNext;
1951 mid->FreeNext = NULL; // This mid is current tail in the FreeHead list
1952 mid = next;
1953 cur->omInUseCount--;
1954 nScavenged ++ ;
1955 } else {
1956 curmidinuse = mid;
1957 mid = mid->FreeNext;
1958 nInuse ++;
1959 }
1960 }
1961 }
1962 } else for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) {
1781 // Iterate over all extant monitors - Scavenge all idle monitors. 1963 // Iterate over all extant monitors - Scavenge all idle monitors.
1782 TEVENT (deflate_idle_monitors) ;
1783 for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) {
1784 assert(block->object() == CHAINMARKER, "must be a block header"); 1964 assert(block->object() == CHAINMARKER, "must be a block header");
1785 nInCirculation += _BLOCKSIZE ; 1965 nInCirculation += _BLOCKSIZE ;
1786 for (int i = 1 ; i < _BLOCKSIZE; i++) { 1966 for (int i = 1 ; i < _BLOCKSIZE; i++) {
1787 ObjectMonitor* mid = &block[i]; 1967 ObjectMonitor* mid = &block[i];
1788 oop obj = (oop) mid->object(); 1968 oop obj = (oop) mid->object();
1793 // free list or the global free list. 1973 // free list or the global free list.
1794 // obj == NULL IMPLIES mid->is_busy() == 0 1974 // obj == NULL IMPLIES mid->is_busy() == 0
1795 guarantee (!mid->is_busy(), "invariant") ; 1975 guarantee (!mid->is_busy(), "invariant") ;
1796 continue ; 1976 continue ;
1797 } 1977 }
1798 1978 deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail);
1799 // Normal case ... The monitor is associated with obj. 1979
1800 guarantee (obj->mark() == markOopDesc::encode(mid), "invariant") ; 1980 if (deflated) {
1801 guarantee (mid == obj->mark()->monitor(), "invariant"); 1981 mid->FreeNext = NULL ;
1802 guarantee (mid->header()->is_neutral(), "invariant"); 1982 nScavenged ++ ;
1803
1804 if (mid->is_busy()) {
1805 if (ClearResponsibleAtSTW) mid->_Responsible = NULL ;
1806 nInuse ++ ;
1807 } else { 1983 } else {
1808 // Deflate the monitor if it is no longer being used 1984 nInuse ++;
1809 // It's idle - scavenge and return to the global free list
1810 // plain old deflation ...
1811 TEVENT (deflate_idle_monitors - scavenge1) ;
1812 if (TraceMonitorInflation) {
1813 if (obj->is_instance()) {
1814 ResourceMark rm;
1815 tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
1816 (intptr_t) obj, (intptr_t) obj->mark(), Klass::cast(obj->klass())->external_name());
1817 }
1818 }
1819
1820 // Restore the header back to obj
1821 obj->release_set_mark(mid->header());
1822 mid->clear();
1823
1824 assert (mid->object() == NULL, "invariant") ;
1825
1826 // Move the object to the working free list defined by FreeHead,FreeTail.
1827 mid->FreeNext = NULL ;
1828 if (FreeHead == NULL) FreeHead = mid ;
1829 if (FreeTail != NULL) FreeTail->FreeNext = mid ;
1830 FreeTail = mid ;
1831 nScavenged ++ ;
1832 } 1985 }
1833 } 1986 }
1834 } 1987 }
1835 1988
1989 MonitorFreeCount += nScavenged;
1990
1991 // Consider: audit gFreeList to ensure that MonitorFreeCount and list agree.
1992
1993 if (Knob_Verbose) {
1994 ::printf ("Deflate: InCirc=%d InUse=%d Scavenged=%d ForceMonitorScavenge=%d : pop=%d free=%d\n",
1995 nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
1996 MonitorPopulation, MonitorFreeCount) ;
1997 ::fflush(stdout) ;
1998 }
1999
2000 ForceMonitorScavenge = 0; // Reset
2001
1836 // Move the scavenged monitors back to the global free list. 2002 // Move the scavenged monitors back to the global free list.
1837 // In theory we don't need the freelist lock as we're at a STW safepoint.
1838 // omAlloc() and omFree() can only be called while a thread is _not in safepoint state.
1839 // But it's remotely possible that omFlush() or release_monitors_owned_by_thread()
1840 // might be called while not at a global STW safepoint. In the interest of
1841 // safety we protect the following access with ListLock.
1842 // An even more conservative and prudent approach would be to guard
1843 // the main loop in scavenge_idle_monitors() with ListLock.
1844 if (FreeHead != NULL) { 2003 if (FreeHead != NULL) {
1845 guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ; 2004 guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ;
1846 assert (FreeTail->FreeNext == NULL, "invariant") ; 2005 assert (FreeTail->FreeNext == NULL, "invariant") ;
1847 // constant-time list splice - prepend scavenged segment to gFreeList 2006 // constant-time list splice - prepend scavenged segment to gFreeList
1848 Thread::muxAcquire (&ListLock, "scavenge - return") ;
1849 FreeTail->FreeNext = gFreeList ; 2007 FreeTail->FreeNext = gFreeList ;
1850 gFreeList = FreeHead ; 2008 gFreeList = FreeHead ;
1851 Thread::muxRelease (&ListLock) ; 2009 }
1852 } 2010 Thread::muxRelease (&ListLock) ;
1853 2011
1854 if (_sync_Deflations != NULL) _sync_Deflations->inc(nScavenged) ; 2012 if (_sync_Deflations != NULL) _sync_Deflations->inc(nScavenged) ;
1855 if (_sync_MonExtant != NULL) _sync_MonExtant ->set_value(nInCirculation); 2013 if (_sync_MonExtant != NULL) _sync_MonExtant ->set_value(nInCirculation);
1856 2014
1857 // TODO: Add objectMonitor leak detection. 2015 // TODO: Add objectMonitor leak detection.