1048 // More precisely, trigger an asynchronous STW safepoint as the number |
1048 // More precisely, trigger an asynchronous STW safepoint as the number |
1049 // of active monitors passes the specified threshold. |
1049 // of active monitors passes the specified threshold. |
1050 // TODO: assert thread state is reasonable |
1050 // TODO: assert thread state is reasonable |
1051 |
1051 |
1052 if (ForceMonitorScavenge == 0 && Atomic::xchg (1, &ForceMonitorScavenge) == 0) { |
1052 if (ForceMonitorScavenge == 0 && Atomic::xchg (1, &ForceMonitorScavenge) == 0) { |
1053 if (ObjectMonitor::Knob_Verbose) { |
|
1054 tty->print_cr("INFO: Monitor scavenge - Induced STW @%s (%d)", |
|
1055 Whence, ForceMonitorScavenge) ; |
|
1056 tty->flush(); |
|
1057 } |
|
1058 // Induce a 'null' safepoint to scavenge monitors |
1053 // Induce a 'null' safepoint to scavenge monitors |
1059 // Must VM_Operation instance be heap allocated as the op will be enqueue and posted |
1054 // Must VM_Operation instance be heap allocated as the op will be enqueue and posted |
1060 // to the VMthread and have a lifespan longer than that of this activation record. |
1055 // to the VMthread and have a lifespan longer than that of this activation record. |
1061 // The VMThread will delete the op when completed. |
1056 // The VMThread will delete the op when completed. |
1062 VMThread::execute(new VM_ScavengeMonitors()); |
1057 VMThread::execute(new VM_ScavengeMonitors()); |
1063 |
1058 } |
1064 if (ObjectMonitor::Knob_Verbose) { |
|
1065 tty->print_cr("INFO: Monitor scavenge - STW posted @%s (%d)", |
|
1066 Whence, ForceMonitorScavenge) ; |
|
1067 tty->flush(); |
|
1068 } |
|
1069 } |
|
1070 } |
|
1071 |
|
1072 void ObjectSynchronizer::verifyInUse(Thread *Self) { |
|
1073 ObjectMonitor* mid; |
|
1074 int in_use_tally = 0; |
|
1075 for (mid = Self->omInUseList; mid != NULL; mid = mid->FreeNext) { |
|
1076 in_use_tally++; |
|
1077 } |
|
1078 assert(in_use_tally == Self->omInUseCount, "in-use count off"); |
|
1079 |
|
1080 int free_tally = 0; |
|
1081 for (mid = Self->omFreeList; mid != NULL; mid = mid->FreeNext) { |
|
1082 free_tally++; |
|
1083 } |
|
1084 assert(free_tally == Self->omFreeCount, "free count off"); |
|
1085 } |
1059 } |
1086 |
1060 |
1087 ObjectMonitor* ObjectSynchronizer::omAlloc(Thread * Self) { |
1061 ObjectMonitor* ObjectSynchronizer::omAlloc(Thread * Self) { |
1088 // A large MAXPRIVATE value reduces both list lock contention |
1062 // A large MAXPRIVATE value reduces both list lock contention |
1089 // and list coherency traffic, but also tends to increase the |
1063 // and list coherency traffic, but also tends to increase the |
1108 guarantee(m->object() == NULL, "invariant"); |
1082 guarantee(m->object() == NULL, "invariant"); |
1109 if (MonitorInUseLists) { |
1083 if (MonitorInUseLists) { |
1110 m->FreeNext = Self->omInUseList; |
1084 m->FreeNext = Self->omInUseList; |
1111 Self->omInUseList = m; |
1085 Self->omInUseList = m; |
1112 Self->omInUseCount++; |
1086 Self->omInUseCount++; |
1113 if (ObjectMonitor::Knob_VerifyInUse) { |
|
1114 verifyInUse(Self); |
|
1115 } |
|
1116 } else { |
1087 } else { |
1117 m->FreeNext = NULL; |
1088 m->FreeNext = NULL; |
1118 } |
1089 } |
1119 return m; |
1090 return m; |
1120 } |
1091 } |
1248 } else if (cur_mid_in_use != NULL) { |
1219 } else if (cur_mid_in_use != NULL) { |
1249 cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list |
1220 cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list |
1250 } |
1221 } |
1251 extracted = true; |
1222 extracted = true; |
1252 Self->omInUseCount--; |
1223 Self->omInUseCount--; |
1253 if (ObjectMonitor::Knob_VerifyInUse) { |
|
1254 verifyInUse(Self); |
|
1255 } |
|
1256 break; |
1224 break; |
1257 } |
1225 } |
1258 } |
1226 } |
1259 assert(extracted, "Should have extracted from in-use list"); |
1227 assert(extracted, "Should have extracted from in-use list"); |
1260 } |
1228 } |
1761 void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* counters) { |
1729 void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* counters) { |
1762 gMonitorFreeCount += counters->nScavenged; |
1730 gMonitorFreeCount += counters->nScavenged; |
1763 |
1731 |
1764 // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree. |
1732 // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree. |
1765 |
1733 |
1766 if (ObjectMonitor::Knob_Verbose) { |
|
1767 tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d " |
|
1768 "ForceMonitorScavenge=%d : pop=%d free=%d", |
|
1769 counters->nInCirculation, counters->nInuse, counters->nScavenged, ForceMonitorScavenge, |
|
1770 gMonitorPopulation, gMonitorFreeCount); |
|
1771 tty->flush(); |
|
1772 } |
|
1773 |
|
1774 ForceMonitorScavenge = 0; // Reset |
1734 ForceMonitorScavenge = 0; // Reset |
1775 |
1735 |
1776 OM_PERFDATA_OP(Deflations, inc(counters->nScavenged)); |
1736 OM_PERFDATA_OP(Deflations, inc(counters->nScavenged)); |
1777 OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation)); |
1737 OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation)); |
1778 |
1738 |
1794 Thread::muxAcquire(&gListLock, "scavenge - return"); |
1754 Thread::muxAcquire(&gListLock, "scavenge - return"); |
1795 |
1755 |
1796 // Adjust counters |
1756 // Adjust counters |
1797 counters->nInCirculation += thread->omInUseCount; |
1757 counters->nInCirculation += thread->omInUseCount; |
1798 thread->omInUseCount -= deflated_count; |
1758 thread->omInUseCount -= deflated_count; |
1799 if (ObjectMonitor::Knob_VerifyInUse) { |
|
1800 verifyInUse(thread); |
|
1801 } |
|
1802 counters->nScavenged += deflated_count; |
1759 counters->nScavenged += deflated_count; |
1803 counters->nInuse += thread->omInUseCount; |
1760 counters->nInuse += thread->omInUseCount; |
1804 |
1761 |
1805 // Move the scavenged monitors back to the global free list. |
1762 // Move the scavenged monitors back to the global free list. |
1806 if (freeHeadp != NULL) { |
1763 if (freeHeadp != NULL) { |
1825 |
1782 |
1826 public: |
1783 public: |
1827 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {} |
1784 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {} |
1828 void do_monitor(ObjectMonitor* mid) { |
1785 void do_monitor(ObjectMonitor* mid) { |
1829 if (mid->owner() == THREAD) { |
1786 if (mid->owner() == THREAD) { |
1830 if (ObjectMonitor::Knob_VerifyMatch != 0) { |
|
1831 ResourceMark rm; |
|
1832 Handle obj(THREAD, (oop) mid->object()); |
|
1833 tty->print("INFO: unexpected locked object:"); |
|
1834 javaVFrame::print_locked_object_class_name(tty, obj, "locked"); |
|
1835 fatal("exiting JavaThread=" INTPTR_FORMAT |
|
1836 " unexpectedly owns ObjectMonitor=" INTPTR_FORMAT, |
|
1837 p2i(THREAD), p2i(mid)); |
|
1838 } |
|
1839 (void)mid->complete_exit(CHECK); |
1787 (void)mid->complete_exit(CHECK); |
1840 } |
1788 } |
1841 } |
1789 } |
1842 }; |
1790 }; |
1843 |
1791 |