@@ -1351,11 +1351,11 @@ void ShenandoahHeap::parallel_heap_region_iterate(ShenandoahHeapRegionClosure* b
1351
1351
}
1352
1352
}
1353
1353
1354
- class ShenandoahClearLivenessClosure : public ShenandoahHeapRegionClosure {
1354
+ class ShenandoahInitMarkUpdateRegionStateClosure : public ShenandoahHeapRegionClosure {
1355
1355
private:
1356
1356
ShenandoahMarkingContext* const _ctx;
1357
1357
public:
1358
- ShenandoahClearLivenessClosure () : _ctx(ShenandoahHeap::heap()->marking_context ()) {}
1358
+ ShenandoahInitMarkUpdateRegionStateClosure () : _ctx(ShenandoahHeap::heap()->marking_context ()) {}
1359
1359
1360
1360
void heap_region_do (ShenandoahHeapRegion* r) {
1361
1361
if (r->is_active ()) {
@@ -1395,9 +1395,9 @@ void ShenandoahHeap::op_init_mark() {
1395
1395
}
1396
1396
1397
1397
{
1398
- ShenandoahGCPhase phase (ShenandoahPhaseTimings::clear_liveness );
1399
- ShenandoahClearLivenessClosure clc ;
1400
- parallel_heap_region_iterate (&clc );
1398
+ ShenandoahGCPhase phase (ShenandoahPhaseTimings::init_update_region_states );
1399
+ ShenandoahInitMarkUpdateRegionStateClosure cl ;
1400
+ parallel_heap_region_iterate (&cl );
1401
1401
}
1402
1402
1403
1403
// Make above changes visible to worker threads
@@ -1426,19 +1426,43 @@ void ShenandoahHeap::op_mark() {
1426
1426
concurrent_mark ()->mark_from_roots ();
1427
1427
}
1428
1428
1429
- class ShenandoahCompleteLivenessClosure : public ShenandoahHeapRegionClosure {
1429
+ class ShenandoahFinalMarkUpdateRegionStateClosure : public ShenandoahHeapRegionClosure {
1430
1430
private:
1431
1431
ShenandoahMarkingContext* const _ctx;
1432
+ ShenandoahHeapLock* const _lock;
1433
+
1432
1434
public:
1433
- ShenandoahCompleteLivenessClosure () : _ctx(ShenandoahHeap::heap()->complete_marking_context ()) {}
1435
+ ShenandoahFinalMarkUpdateRegionStateClosure () :
1436
+ _ctx (ShenandoahHeap::heap()->complete_marking_context ()), _lock(ShenandoahHeap::heap()->lock()) {}
1434
1437
1435
1438
void heap_region_do (ShenandoahHeapRegion* r) {
1436
1439
if (r->is_active ()) {
1440
+ // All allocations past TAMS are implicitly live, adjust the region data.
1441
+ // Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap.
1437
1442
HeapWord *tams = _ctx->top_at_mark_start (r);
1438
1443
HeapWord *top = r->top ();
1439
1444
if (top > tams) {
1440
1445
r->increase_live_data_alloc_words (pointer_delta (top, tams));
1441
1446
}
1447
+
1448
+ // We are about to select the collection set, make sure it knows about
1449
+ // current pinning status. Also, this allows trashing more regions that
1450
+ // now have their pinning status dropped.
1451
+ if (r->is_pinned ()) {
1452
+ if (r->pin_count () == 0 ) {
1453
+ ShenandoahHeapLocker locker (_lock);
1454
+ r->make_unpinned ();
1455
+ }
1456
+ } else {
1457
+ if (r->pin_count () > 0 ) {
1458
+ ShenandoahHeapLocker locker (_lock);
1459
+ r->make_pinned ();
1460
+ }
1461
+ }
1462
+
1463
+ // Remember limit for updating refs. It's guaranteed that we get no
1464
+ // from-space-refs written from here on.
1465
+ r->set_update_watermark (r->top ());
1442
1466
} else {
1443
1467
assert (!r->has_live (), " Region " SIZE_FORMAT " should have no live data" , r->index ());
1444
1468
assert (_ctx->top_at_mark_start (r) == r->top (),
@@ -1469,12 +1493,13 @@ void ShenandoahHeap::op_final_mark() {
1469
1493
if (ShenandoahVerify) {
1470
1494
verifier ()->verify_roots_no_forwarded ();
1471
1495
}
1472
- // All allocations past TAMS are implicitly live, adjust the region data.
1473
- // Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap.
1496
+
1474
1497
{
1475
- ShenandoahGCPhase phase (ShenandoahPhaseTimings::complete_liveness );
1476
- ShenandoahCompleteLivenessClosure cl;
1498
+ ShenandoahGCPhase phase (ShenandoahPhaseTimings::final_update_region_states );
1499
+ ShenandoahFinalMarkUpdateRegionStateClosure cl;
1477
1500
parallel_heap_region_iterate (&cl);
1501
+
1502
+ assert_pinned_region_status ();
1478
1503
}
1479
1504
1480
1505
// Force the threads to reacquire their TLABs outside the collection set.
@@ -1483,14 +1508,6 @@ void ShenandoahHeap::op_final_mark() {
1483
1508
make_parsable (true );
1484
1509
}
1485
1510
1486
- // We are about to select the collection set, make sure it knows about
1487
- // current pinning status. Also, this allows trashing more regions that
1488
- // now have their pinning status dropped.
1489
- {
1490
- ShenandoahGCPhase phase (ShenandoahPhaseTimings::sync_pinned);
1491
- sync_pinned_region_status ();
1492
- }
1493
-
1494
1511
{
1495
1512
ShenandoahGCPhase phase (ShenandoahPhaseTimings::choose_cset);
1496
1513
ShenandoahHeapLocker locker (lock ());
@@ -1518,13 +1535,6 @@ void ShenandoahHeap::op_final_mark() {
1518
1535
verifier ()->verify_before_evacuation ();
1519
1536
}
1520
1537
1521
- // Remember limit for updating refs. It's guaranteed that we get no from-space-refs written
1522
- // from here on.
1523
- for (uint i = 0 ; i < num_regions (); i++) {
1524
- ShenandoahHeapRegion* r = get_region (i);
1525
- r->set_update_watermark (r->top ());
1526
- }
1527
-
1528
1538
set_evacuation_in_progress (true );
1529
1539
// From here on, we need to update references.
1530
1540
set_has_forwarded_objects (true );
@@ -2397,6 +2407,35 @@ void ShenandoahHeap::op_init_updaterefs() {
2397
2407
}
2398
2408
}
2399
2409
2410
+ class ShenandoahFinalUpdateRefsUpdateRegionStateClosure : public ShenandoahHeapRegionClosure {
2411
+ private:
2412
+ ShenandoahHeapLock* const _lock;
2413
+
2414
+ public:
2415
+ ShenandoahFinalUpdateRefsUpdateRegionStateClosure () : _lock(ShenandoahHeap::heap()->lock ()) {}
2416
+
2417
+ void heap_region_do (ShenandoahHeapRegion* r) {
2418
+ // Drop unnecessary "pinned" state from regions that does not have CP marks
2419
+ // anymore, as this would allow trashing them.
2420
+
2421
+ if (r->is_active ()) {
2422
+ if (r->is_pinned ()) {
2423
+ if (r->pin_count () == 0 ) {
2424
+ ShenandoahHeapLocker locker (_lock);
2425
+ r->make_unpinned ();
2426
+ }
2427
+ } else {
2428
+ if (r->pin_count () > 0 ) {
2429
+ ShenandoahHeapLocker locker (_lock);
2430
+ r->make_pinned ();
2431
+ }
2432
+ }
2433
+ }
2434
+ }
2435
+
2436
+ bool is_thread_safe () { return true ; }
2437
+ };
2438
+
2400
2439
void ShenandoahHeap::op_final_updaterefs () {
2401
2440
assert (ShenandoahSafepoint::is_at_shenandoah_safepoint (), " must be at safepoint" );
2402
2441
@@ -2433,11 +2472,12 @@ void ShenandoahHeap::op_final_updaterefs() {
2433
2472
verifier ()->verify_roots_in_to_space ();
2434
2473
}
2435
2474
2436
- // Drop unnecessary "pinned" state from regions that does not have CP marks
2437
- // anymore, as this would allow trashing them below.
2438
2475
{
2439
- ShenandoahGCPhase phase (ShenandoahPhaseTimings::final_update_refs_sync_pinned);
2440
- sync_pinned_region_status ();
2476
+ ShenandoahGCPhase phase (ShenandoahPhaseTimings::final_update_refs_update_region_states);
2477
+ ShenandoahFinalUpdateRefsUpdateRegionStateClosure cl;
2478
+ parallel_heap_region_iterate (&cl);
2479
+
2480
+ assert_pinned_region_status ();
2441
2481
}
2442
2482
2443
2483
{
0 commit comments