1269 if (ParGCUseLocalOverflow) {
1270 // In the case of compressed oops, we use a private, not-shared
1271 // overflow stack.
1272 par_scan_state->push_on_overflow_stack(from_space_obj);
1273 } else {
1274 assert(!UseCompressedOops, "Error");
1275 // if the object has been forwarded to itself, then we cannot
1276 // use the klass pointer for the linked list. Instead we have
1277 // to allocate an oopDesc in the C-Heap and use that for the linked list.
1278 // XXX This is horribly inefficient when a promotion failure occurs
1279 // and should be fixed. XXX FIX ME !!!
1280 #ifndef PRODUCT
1281 Atomic::inc_ptr(&_num_par_pushes);
1282 assert(_num_par_pushes > 0, "Tautology");
1283 #endif
1284 if (from_space_obj->forwardee() == from_space_obj) {
1285 oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1, mtGC);
1286 listhead->forward_to(from_space_obj);
1287 from_space_obj = listhead;
1288 }
1289 oop observed_overflow_list = _overflow_list;
1290 oop cur_overflow_list;
1291 do {
1292 cur_overflow_list = observed_overflow_list;
1293 if (cur_overflow_list != BUSY) {
1294 from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
1295 } else {
1296 from_space_obj->set_klass_to_list_ptr(NULL);
1297 }
1298 observed_overflow_list =
1299 (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
1300 } while (cur_overflow_list != observed_overflow_list);
1301 }
1302 }
1303
1304 bool ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
1305 bool res;
1306
1307 if (ParGCUseLocalOverflow) {
1308 res = par_scan_state->take_from_overflow_stack();
1309 } else {
1369 size_t i = 1;
1370 oop cur = prefix;
1371 while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
1372 i++; cur = cur->list_ptr_from_klass();
1373 }
1374
1375 // Reattach remaining (suffix) to overflow list
1376 if (cur->klass_or_null() == NULL) {
1377 // Write back the NULL in lieu of the BUSY we wrote
1378 // above and it is still the same value.
1379 if (_overflow_list == BUSY) {
1380 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
1381 }
1382 } else {
1383 assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
1384 oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list
1385 cur->set_klass_to_list_ptr(NULL); // break off suffix
1386 // It's possible that the list is still in the empty(busy) state
1387 // we left it in a short while ago; in that case we may be
1388 // able to place back the suffix.
1389 oop observed_overflow_list = _overflow_list;
1390 oop cur_overflow_list = observed_overflow_list;
1391 bool attached = false;
1392 while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1393 observed_overflow_list =
1394 (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1395 if (cur_overflow_list == observed_overflow_list) {
1396 attached = true;
1397 break;
1398 } else cur_overflow_list = observed_overflow_list;
1399 }
1400 if (!attached) {
1401 // Too bad, someone else got in in between; we'll need to do a splice.
1402 // Find the last item of suffix list
1403 oop last = suffix;
1404 while (last->klass_or_null() != NULL) {
1405 last = last->list_ptr_from_klass();
1406 }
1407 // Atomically prepend suffix to current overflow list
1408 observed_overflow_list = _overflow_list;
1409 do {
1410 cur_overflow_list = observed_overflow_list;
1411 if (cur_overflow_list != BUSY) {
1412 // Do the splice ...
1413 last->set_klass_to_list_ptr(cur_overflow_list);
1414 } else { // cur_overflow_list == BUSY
1415 last->set_klass_to_list_ptr(NULL);
1416 }
1417 observed_overflow_list =
1418 (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1419 } while (cur_overflow_list != observed_overflow_list);
1420 }
1421 }
1422
1423 // Push objects on prefix list onto this thread's work queue
1424 assert(prefix != NULL && prefix != BUSY, "program logic");
1425 cur = prefix;
1426 ssize_t n = 0;
1427 while (cur != NULL) {
1428 oop obj_to_push = cur->forwardee();
|
1269 if (ParGCUseLocalOverflow) {
1270 // In the case of compressed oops, we use a private, not-shared
1271 // overflow stack.
1272 par_scan_state->push_on_overflow_stack(from_space_obj);
1273 } else {
1274 assert(!UseCompressedOops, "Error");
1275 // if the object has been forwarded to itself, then we cannot
1276 // use the klass pointer for the linked list. Instead we have
1277 // to allocate an oopDesc in the C-Heap and use that for the linked list.
1278 // XXX This is horribly inefficient when a promotion failure occurs
1279 // and should be fixed. XXX FIX ME !!!
1280 #ifndef PRODUCT
1281 Atomic::inc_ptr(&_num_par_pushes);
1282 assert(_num_par_pushes > 0, "Tautology");
1283 #endif
1284 if (from_space_obj->forwardee() == from_space_obj) {
1285 oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1, mtGC);
1286 listhead->forward_to(from_space_obj);
1287 from_space_obj = listhead;
1288 }
1289 oop observed_overflow_list = oop(_overflow_list);
1290 oop cur_overflow_list;
1291 do {
1292 cur_overflow_list = observed_overflow_list;
1293 if (cur_overflow_list != BUSY) {
1294 from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
1295 } else {
1296 from_space_obj->set_klass_to_list_ptr(NULL);
1297 }
1298 observed_overflow_list =
1299 (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
1300 } while (cur_overflow_list != observed_overflow_list);
1301 }
1302 }
1303
1304 bool ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
1305 bool res;
1306
1307 if (ParGCUseLocalOverflow) {
1308 res = par_scan_state->take_from_overflow_stack();
1309 } else {
1369 size_t i = 1;
1370 oop cur = prefix;
1371 while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
1372 i++; cur = cur->list_ptr_from_klass();
1373 }
1374
1375 // Reattach remaining (suffix) to overflow list
1376 if (cur->klass_or_null() == NULL) {
1377 // Write back the NULL in lieu of the BUSY we wrote
1378 // above and it is still the same value.
1379 if (_overflow_list == BUSY) {
1380 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
1381 }
1382 } else {
1383 assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
1384 oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list
1385 cur->set_klass_to_list_ptr(NULL); // break off suffix
1386 // It's possible that the list is still in the empty(busy) state
1387 // we left it in a short while ago; in that case we may be
1388 // able to place back the suffix.
1389 oop observed_overflow_list = oop(_overflow_list);
1390 oop cur_overflow_list = observed_overflow_list;
1391 bool attached = false;
1392 while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1393 observed_overflow_list =
1394 (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1395 if (cur_overflow_list == observed_overflow_list) {
1396 attached = true;
1397 break;
1398 } else cur_overflow_list = observed_overflow_list;
1399 }
1400 if (!attached) {
1401 // Too bad, someone else got in in between; we'll need to do a splice.
1402 // Find the last item of suffix list
1403 oop last = suffix;
1404 while (last->klass_or_null() != NULL) {
1405 last = last->list_ptr_from_klass();
1406 }
1407 // Atomically prepend suffix to current overflow list
1408 observed_overflow_list = oop(_overflow_list);
1409 do {
1410 cur_overflow_list = observed_overflow_list;
1411 if (cur_overflow_list != BUSY) {
1412 // Do the splice ...
1413 last->set_klass_to_list_ptr(cur_overflow_list);
1414 } else { // cur_overflow_list == BUSY
1415 last->set_klass_to_list_ptr(NULL);
1416 }
1417 observed_overflow_list =
1418 (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1419 } while (cur_overflow_list != observed_overflow_list);
1420 }
1421 }
1422
1423 // Push objects on prefix list onto this thread's work queue
1424 assert(prefix != NULL && prefix != BUSY, "program logic");
1425 cur = prefix;
1426 ssize_t n = 0;
1427 while (cur != NULL) {
1428 oop obj_to_push = cur->forwardee();
|