< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page




1160       Thread::muxRelease(&gListLock);
1161       Self->omFreeProvision += 1 + (Self->omFreeProvision/2);
1162       if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE;
1163       TEVENT(omFirst - reprovision);
1164 
1165       const int mx = MonitorBound;
1166       if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) {
1167         // We can't safely induce a STW safepoint from omAlloc() as our thread
1168         // state may not be appropriate for such activities and callers may hold
1169         // naked oops, so instead we defer the action.
1170         InduceScavenge(Self, "omAlloc");
1171       }
1172       continue;
1173     }
1174 
1175     // 3: allocate a block of new ObjectMonitors
1176     // Both the local and global free lists are empty -- resort to malloc().
1177     // In the current implementation objectMonitors are TSM - immortal.
1178     // Ideally, we'd write "new ObjectMonitor[_BLOCKSIZE], but we want
1179     // each ObjectMonitor to start at the beginning of a cache line,
1180     // so we use align_size_up().
1181     // A better solution would be to use C++ placement-new.
1182     // BEWARE: As it stands currently, we don't run the ctors!
1183     assert(_BLOCKSIZE > 1, "invariant");
1184     size_t neededsize = sizeof(PaddedEnd<ObjectMonitor>) * _BLOCKSIZE;
1185     PaddedEnd<ObjectMonitor> * temp;
1186     size_t aligned_size = neededsize + (DEFAULT_CACHE_LINE_SIZE - 1);
1187     void* real_malloc_addr = (void *)NEW_C_HEAP_ARRAY(char, aligned_size,
1188                                                       mtInternal);
1189     temp = (PaddedEnd<ObjectMonitor> *)
1190              align_ptr_up(real_malloc_addr,
1191                            DEFAULT_CACHE_LINE_SIZE);
1192 
1193     // NOTE: (almost) no way to recover if allocation failed.
1194     // We might be able to induce a STW safepoint and scavenge enough
1195     // objectMonitors to permit progress.
1196     if (temp == NULL) {
1197       vm_exit_out_of_memory(neededsize, OOM_MALLOC_ERROR,
1198                             "Allocate ObjectMonitors");
1199     }
1200     (void)memset((void *) temp, 0, neededsize);
1201 
1202     // Format the block.
1203     // initialize the linked list, each monitor points to its next
1204     // forming the single linked free list, the very first monitor
1205     // will points to next block, which forms the block list.
1206     // The trick of using the 1st element in the block as gBlockList
1207     // linkage should be reconsidered.  A better implementation would
1208     // look like: class Block { Block * next; int N; ObjectMonitor Body [N] ; }
1209 
1210     for (int i = 1; i < _BLOCKSIZE; i++) {




1160       Thread::muxRelease(&gListLock);
1161       Self->omFreeProvision += 1 + (Self->omFreeProvision/2);
1162       if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE;
1163       TEVENT(omFirst - reprovision);
1164 
1165       const int mx = MonitorBound;
1166       if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) {
1167         // We can't safely induce a STW safepoint from omAlloc() as our thread
1168         // state may not be appropriate for such activities and callers may hold
1169         // naked oops, so instead we defer the action.
1170         InduceScavenge(Self, "omAlloc");
1171       }
1172       continue;
1173     }
1174 
1175     // 3: allocate a block of new ObjectMonitors
1176     // Both the local and global free lists are empty -- resort to malloc().
1177     // In the current implementation objectMonitors are TSM - immortal.
1178     // Ideally, we'd write "new ObjectMonitor[_BLOCKSIZE], but we want
1179     // each ObjectMonitor to start at the beginning of a cache line,
1180     // so we use align_up().
1181     // A better solution would be to use C++ placement-new.
1182     // BEWARE: As it stands currently, we don't run the ctors!
1183     assert(_BLOCKSIZE > 1, "invariant");
1184     size_t neededsize = sizeof(PaddedEnd<ObjectMonitor>) * _BLOCKSIZE;
1185     PaddedEnd<ObjectMonitor> * temp;
1186     size_t aligned_size = neededsize + (DEFAULT_CACHE_LINE_SIZE - 1);
1187     void* real_malloc_addr = (void *)NEW_C_HEAP_ARRAY(char, aligned_size,
1188                                                       mtInternal);
1189     temp = (PaddedEnd<ObjectMonitor> *)
1190              align_up(real_malloc_addr,
1191                            DEFAULT_CACHE_LINE_SIZE);
1192 
1193     // NOTE: (almost) no way to recover if allocation failed.
1194     // We might be able to induce a STW safepoint and scavenge enough
1195     // objectMonitors to permit progress.
1196     if (temp == NULL) {
1197       vm_exit_out_of_memory(neededsize, OOM_MALLOC_ERROR,
1198                             "Allocate ObjectMonitors");
1199     }
1200     (void)memset((void *) temp, 0, neededsize);
1201 
1202     // Format the block.
1203     // initialize the linked list, each monitor points to its next
1204     // forming the single linked free list, the very first monitor
1205     // will points to next block, which forms the block list.
1206     // The trick of using the 1st element in the block as gBlockList
1207     // linkage should be reconsidered.  A better implementation would
1208     // look like: class Block { Block * next; int N; ObjectMonitor Body [N] ; }
1209 
1210     for (int i = 1; i < _BLOCKSIZE; i++) {


< prev index next >