109 |
109 |
110 #define NINFLATIONLOCKS 256 |
110 #define NINFLATIONLOCKS 256 |
111 static volatile intptr_t gInflationLocks[NINFLATIONLOCKS]; |
111 static volatile intptr_t gInflationLocks[NINFLATIONLOCKS]; |
112 |
112 |
113 // global list of blocks of monitors |
113 // global list of blocks of monitors |
114 // gBlockList is really PaddedEnd<ObjectMonitor> *, but we don't |
114 PaddedEnd<ObjectMonitor> * volatile ObjectSynchronizer::gBlockList = NULL; |
115 // want to expose the PaddedEnd template more than necessary. |
|
116 ObjectMonitor * volatile ObjectSynchronizer::gBlockList = NULL; |
|
117 // global monitor free list |
115 // global monitor free list |
118 ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL; |
116 ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL; |
119 // global monitor in-use list, for moribund threads, |
117 // global monitor in-use list, for moribund threads, |
120 // monitors they inflated need to be scanned for deflation |
118 // monitors they inflated need to be scanned for deflation |
121 ObjectMonitor * volatile ObjectSynchronizer::gOmInUseList = NULL; |
119 ObjectMonitor * volatile ObjectSynchronizer::gOmInUseList = NULL; |
239 // recursive stack-locking in the displaced header in the BasicLock, |
237 // recursive stack-locking in the displaced header in the BasicLock, |
240 // and last are the inflated Java Monitor (ObjectMonitor) checks. |
238 // and last are the inflated Java Monitor (ObjectMonitor) checks. |
241 lock->set_displaced_header(markOopDesc::unused_mark()); |
239 lock->set_displaced_header(markOopDesc::unused_mark()); |
242 |
240 |
243 if (owner == NULL && |
241 if (owner == NULL && |
244 Atomic::cmpxchg_ptr(Self, &(m->_owner), NULL) == NULL) { |
242 Atomic::cmpxchg(Self, &(m->_owner), (void*)NULL) == NULL) { |
245 assert(m->_recursions == 0, "invariant"); |
243 assert(m->_recursions == 0, "invariant"); |
246 assert(m->_owner == Self, "invariant"); |
244 assert(m->_owner == Self, "invariant"); |
247 return true; |
245 return true; |
248 } |
246 } |
249 } |
247 } |
800 hash = mark->hash(); |
798 hash = mark->hash(); |
801 if (hash == 0) { |
799 if (hash == 0) { |
802 hash = get_next_hash(Self, obj); |
800 hash = get_next_hash(Self, obj); |
803 temp = mark->copy_set_hash(hash); // merge hash code into header |
801 temp = mark->copy_set_hash(hash); // merge hash code into header |
804 assert(temp->is_neutral(), "invariant"); |
802 assert(temp->is_neutral(), "invariant"); |
805 test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark); |
803 test = Atomic::cmpxchg(temp, monitor->header_addr(), mark); |
806 if (test != mark) { |
804 if (test != mark) { |
807 // The only update to the header in the monitor (outside GC) |
805 // The only update to the header in the monitor (outside GC) |
808 // is install the hash code. If someone add new usage of |
806 // is install the hash code. If someone add new usage of |
809 // displaced header, please update this code |
807 // displaced header, please update this code |
810 hash = test->hash(); |
808 hash = test->hash(); |
937 } |
935 } |
938 |
936 |
939 // Visitors ... |
937 // Visitors ... |
940 |
938 |
941 void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) { |
939 void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) { |
942 PaddedEnd<ObjectMonitor> * block = |
940 PaddedEnd<ObjectMonitor> * block = OrderAccess::load_acquire(&gBlockList); |
943 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); |
|
944 while (block != NULL) { |
941 while (block != NULL) { |
945 assert(block->object() == CHAINMARKER, "must be a block header"); |
942 assert(block->object() == CHAINMARKER, "must be a block header"); |
946 for (int i = _BLOCKSIZE - 1; i > 0; i--) { |
943 for (int i = _BLOCKSIZE - 1; i > 0; i--) { |
947 ObjectMonitor* mid = (ObjectMonitor *)(block + i); |
944 ObjectMonitor* mid = (ObjectMonitor *)(block + i); |
948 oop object = (oop)mid->object(); |
945 oop object = (oop)mid->object(); |
953 block = (PaddedEnd<ObjectMonitor> *)block->FreeNext; |
950 block = (PaddedEnd<ObjectMonitor> *)block->FreeNext; |
954 } |
951 } |
955 } |
952 } |
956 |
953 |
957 // Get the next block in the block list. |
954 // Get the next block in the block list. |
958 static inline ObjectMonitor* next(ObjectMonitor* block) { |
955 static inline PaddedEnd<ObjectMonitor>* next(PaddedEnd<ObjectMonitor>* block) { |
959 assert(block->object() == CHAINMARKER, "must be a block header"); |
956 assert(block->object() == CHAINMARKER, "must be a block header"); |
960 block = block->FreeNext; |
957 block = (PaddedEnd<ObjectMonitor>*) block->FreeNext; |
961 assert(block == NULL || block->object() == CHAINMARKER, "must be a block header"); |
958 assert(block == NULL || block->object() == CHAINMARKER, "must be a block header"); |
962 return block; |
959 return block; |
963 } |
960 } |
964 |
961 |
965 static bool monitors_used_above_threshold() { |
962 static bool monitors_used_above_threshold() { |
989 } |
986 } |
990 } |
987 } |
991 |
988 |
992 void ObjectSynchronizer::global_oops_do(OopClosure* f) { |
989 void ObjectSynchronizer::global_oops_do(OopClosure* f) { |
993 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
990 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
994 PaddedEnd<ObjectMonitor> * block = |
991 PaddedEnd<ObjectMonitor> * block = OrderAccess::load_acquire(&gBlockList); |
995 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); |
992 for (; block != NULL; block = next(block)) { |
996 for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) { |
|
997 assert(block->object() == CHAINMARKER, "must be a block header"); |
993 assert(block->object() == CHAINMARKER, "must be a block header"); |
998 for (int i = 1; i < _BLOCKSIZE; i++) { |
994 for (int i = 1; i < _BLOCKSIZE; i++) { |
999 ObjectMonitor* mid = (ObjectMonitor *)&block[i]; |
995 ObjectMonitor* mid = (ObjectMonitor *)&block[i]; |
1000 if (mid->object() != NULL) { |
996 if (mid->object() != NULL) { |
1001 f->do_oop((oop*)mid->object_addr()); |
997 f->do_oop((oop*)mid->object_addr()); |
1230 // The very first objectMonitor in a block is reserved and dedicated. |
1226 // The very first objectMonitor in a block is reserved and dedicated. |
1231 // It serves as blocklist "next" linkage. |
1227 // It serves as blocklist "next" linkage. |
1232 temp[0].FreeNext = gBlockList; |
1228 temp[0].FreeNext = gBlockList; |
1233 // There are lock-free uses of gBlockList so make sure that |
1229 // There are lock-free uses of gBlockList so make sure that |
1234 // the previous stores happen before we update gBlockList. |
1230 // the previous stores happen before we update gBlockList. |
1235 OrderAccess::release_store_ptr(&gBlockList, temp); |
1231 OrderAccess::release_store(&gBlockList, temp); |
1236 |
1232 |
1237 // Add the new string of objectMonitors to the global free list |
1233 // Add the new string of objectMonitors to the global free list |
1238 temp[_BLOCKSIZE - 1].FreeNext = gFreeList; |
1234 temp[_BLOCKSIZE - 1].FreeNext = gFreeList; |
1239 gFreeList = temp + 1; |
1235 gFreeList = temp + 1; |
1240 Thread::muxRelease(&gListLock); |
1236 Thread::muxRelease(&gListLock); |
1732 counters->nScavenged += deflated_count; |
1728 counters->nScavenged += deflated_count; |
1733 counters->nInuse += gOmInUseCount; |
1729 counters->nInuse += gOmInUseCount; |
1734 } |
1730 } |
1735 |
1731 |
1736 } else { |
1732 } else { |
1737 PaddedEnd<ObjectMonitor> * block = |
1733 PaddedEnd<ObjectMonitor> * block = OrderAccess::load_acquire(&gBlockList); |
1738 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); |
1734 for (; block != NULL; block = next(block)) { |
1739 for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) { |
|
1740 // Iterate over all extant monitors - Scavenge all idle monitors. |
1735 // Iterate over all extant monitors - Scavenge all idle monitors. |
1741 assert(block->object() == CHAINMARKER, "must be a block header"); |
1736 assert(block->object() == CHAINMARKER, "must be a block header"); |
1742 counters->nInCirculation += _BLOCKSIZE; |
1737 counters->nInCirculation += _BLOCKSIZE; |
1743 for (int i = 1; i < _BLOCKSIZE; i++) { |
1738 for (int i = 1; i < _BLOCKSIZE; i++) { |
1744 ObjectMonitor* mid = (ObjectMonitor*)&block[i]; |
1739 ObjectMonitor* mid = (ObjectMonitor*)&block[i]; |
1967 // Check if monitor belongs to the monitor cache |
1962 // Check if monitor belongs to the monitor cache |
1968 // The list is grow-only so it's *relatively* safe to traverse |
1963 // The list is grow-only so it's *relatively* safe to traverse |
1969 // the list of extant blocks without taking a lock. |
1964 // the list of extant blocks without taking a lock. |
1970 |
1965 |
1971 int ObjectSynchronizer::verify_objmon_isinpool(ObjectMonitor *monitor) { |
1966 int ObjectSynchronizer::verify_objmon_isinpool(ObjectMonitor *monitor) { |
1972 PaddedEnd<ObjectMonitor> * block = |
1967 PaddedEnd<ObjectMonitor> * block = OrderAccess::load_acquire(&gBlockList); |
1973 (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); |
|
1974 while (block != NULL) { |
1968 while (block != NULL) { |
1975 assert(block->object() == CHAINMARKER, "must be a block header"); |
1969 assert(block->object() == CHAINMARKER, "must be a block header"); |
1976 if (monitor > (ObjectMonitor *)&block[0] && |
1970 if (monitor > &block[0] && monitor < &block[_BLOCKSIZE]) { |
1977 monitor < (ObjectMonitor *)&block[_BLOCKSIZE]) { |
|
1978 address mon = (address)monitor; |
1971 address mon = (address)monitor; |
1979 address blk = (address)block; |
1972 address blk = (address)block; |
1980 size_t diff = mon - blk; |
1973 size_t diff = mon - blk; |
1981 assert((diff % sizeof(PaddedEnd<ObjectMonitor>)) == 0, "must be aligned"); |
1974 assert((diff % sizeof(PaddedEnd<ObjectMonitor>)) == 0, "must be aligned"); |
1982 return 1; |
1975 return 1; |