@@ -125,7 +125,7 @@ bool ZRemembered::should_scan_page(ZPage* page) const {
125
125
return false ;
126
126
}
127
127
128
- bool ZRemembered::scan_page (ZPage* page) const {
128
+ bool ZRemembered::scan_page_and_clear_remset (ZPage* page) const {
129
129
const bool can_trust_live_bits =
130
130
page->is_relocatable () && !ZGeneration::old ()->is_phase_mark ();
131
131
@@ -151,6 +151,20 @@ bool ZRemembered::scan_page(ZPage* page) const {
151
151
// All objects are dead - do nothing
152
152
}
153
153
154
+ if (ZVerifyRemembered) {
155
+ // Make sure self healing of pointers is ordered before clearing of
156
+ // the previous bits so that ZVerify::after_scan can detect missing
157
+ // remset entries accurately.
158
+ OrderAccess::storestore ();
159
+ }
160
+
161
+ // If we have consumed the remset entries above we also clear them.
162
+ // The exception is if the page is completely empty/garbage, where we don't
163
+ // want to race with an old collection modifying the remset as well.
164
+ if (!can_trust_live_bits || page->is_marked ()) {
165
+ page->clear_remset_previous ();
166
+ }
167
+
154
168
return result;
155
169
}
156
170
@@ -500,16 +514,7 @@ class ZRememberedScanMarkFollowTask : public ZRestartableTask {
500
514
if (page != nullptr ) {
501
515
if (_remembered->should_scan_page (page)) {
502
516
// Visit all entries pointing into young gen
503
- bool found_roots = _remembered->scan_page (page);
504
-
505
- // ... and as a side-effect clear the previous entries
506
- if (ZVerifyRemembered) {
507
- // Make sure self healing of pointers is ordered before clearing of
508
- // the previous bits so that ZVerify::after_scan can detect missing
509
- // remset entries accurately.
510
- OrderAccess::storestore ();
511
- }
512
- page->clear_remset_previous ();
517
+ bool found_roots = _remembered->scan_page_and_clear_remset (page);
513
518
514
519
if (found_roots && !left_marking) {
515
520
// Follow remembered set when possible
0 commit comments