< prev index next >
src/share/vm/gc/g1/heapRegionRemSet.cpp
Print this page
rev 9982 : 8147087: Race when reusing PerRegionTable bitmaps may result in dropped remembered set entries
Summary: Do not make reused PRTs available to other threads before the bitmap of the PRT has been cleared.
Contributed-by: Poonam Bajaj <poonam.bajaj@oracle.com>, Thomas Schatzl <thomas.schatzl@oracle.com>
rev 9983 : [mq]: 8147087-comments
*** 1,7 ****
/*
! * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 108,118 ****
}
}
public:
! HeapRegion* hr() const { return _hr; }
jint occupied() const {
// Overkill, but if we ever need it...
// guarantee(_occupied == _bm.count_one_bits(), "Check");
return _occupied;
--- 108,120 ----
}
}
public:
! HeapRegion* hr() const {
! return (HeapRegion*) OrderAccess::load_ptr_acquire(&_hr);
! }
jint occupied() const {
// Overkill, but if we ever need it...
// guarantee(_occupied == _bm.count_one_bits(), "Check");
return _occupied;
*** 121,134 ****
void init(HeapRegion* hr, bool clear_links_to_all_list) {
if (clear_links_to_all_list) {
set_next(NULL);
set_prev(NULL);
}
- _hr = hr;
_collision_list_next = NULL;
_occupied = 0;
_bm.clear();
}
void add_reference(OopOrNarrowOopStar from) {
add_reference_work(from, /*parallel*/ true);
}
--- 123,138 ----
void init(HeapRegion* hr, bool clear_links_to_all_list) {
if (clear_links_to_all_list) {
set_next(NULL);
set_prev(NULL);
}
_collision_list_next = NULL;
_occupied = 0;
_bm.clear();
+ // Make sure that the bitmap clearing above has been finished before publishing
+ // this PRT to concurrent threads.
+ OrderAccess::release_store_ptr(&_hr, hr);
}
void add_reference(OopOrNarrowOopStar from) {
add_reference_work(from, /*parallel*/ true);
}
*** 355,375 ****
uint cur_hrm_ind = _hr->hrm_index();
int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) {
! assert(contains_reference(from), "We just added it!");
return;
}
// Note that this may be a continued H region.
HeapRegion* from_hr = _g1h->heap_region_containing(from);
RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index();
// If the region is already coarsened, return.
if (_coarse_map.at(from_hrm_ind)) {
! assert(contains_reference(from), "We just added it!");
return;
}
// Otherwise find a per-region table to add it to.
size_t ind = from_hrm_ind & _mod_max_fine_entries_mask;
--- 359,379 ----
uint cur_hrm_ind = _hr->hrm_index();
int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) {
! assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from));
return;
}
// Note that this may be a continued H region.
HeapRegion* from_hr = _g1h->heap_region_containing(from);
RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index();
// If the region is already coarsened, return.
if (_coarse_map.at(from_hrm_ind)) {
! assert(contains_reference(from), "We just found " PTR_FORMAT " in the Coarse table", p2i(from));
return;
}
// Otherwise find a per-region table to add it to.
size_t ind = from_hrm_ind & _mod_max_fine_entries_mask;
*** 386,396 ****
CardIdx_t card_index = from_card - from_hr_bot_card_index;
assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
"Must be in range.");
if (G1HRRSUseSparseTable &&
_sparse_table.add_card(from_hrm_ind, card_index)) {
! assert(contains_reference_locked(from), "We just added it!");
return;
}
if (_n_fine_entries == _max_fine_entries) {
prt = delete_region_table();
--- 390,400 ----
CardIdx_t card_index = from_card - from_hr_bot_card_index;
assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
"Must be in range.");
if (G1HRRSUseSparseTable &&
_sparse_table.add_card(from_hrm_ind, card_index)) {
! assert(contains_reference_locked(from), "We just added " PTR_FORMAT " to the Sparse table", p2i(from));
return;
}
if (_n_fine_entries == _max_fine_entries) {
prt = delete_region_table();
*** 436,446 ****
// possibility of concurrent reuse. But see head comment of
// OtherRegionsTable for why this is OK.
assert(prt != NULL, "Inv");
prt->add_reference(from);
! assert(contains_reference(from), "We just added it!");
}
PerRegionTable*
OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const {
assert(ind < _max_fine_entries, "Preconditions.");
--- 440,450 ----
// possibility of concurrent reuse. But see head comment of
// OtherRegionsTable for why this is OK.
assert(prt != NULL, "Inv");
prt->add_reference(from);
! assert(contains_reference(from), "We just added " PTR_FORMAT " to the PRT", p2i(from));
}
PerRegionTable*
OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const {
assert(ind < _max_fine_entries, "Preconditions.");
< prev index next >