Mercurial > hg > graal-jvmci-8
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. |