src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
Print this page
rev 5869 : [mq]: free-cset-base
*** 1,7 ****
/*
! * Copyright (c) 2001, 2013, 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, 2014, 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.
*** 257,270 ****
size_t OtherRegionsTable::_max_fine_entries = 0;
size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0;
size_t OtherRegionsTable::_fine_eviction_stride = 0;
size_t OtherRegionsTable::_fine_eviction_sample_size = 0;
! OtherRegionsTable::OtherRegionsTable(HeapRegion* hr) :
_g1h(G1CollectedHeap::heap()),
! _m(Mutex::leaf, "An OtherRegionsTable lock", true),
! _hr(hr),
_coarse_map(G1CollectedHeap::heap()->max_regions(),
false /* in-resource-area */),
_fine_grain_regions(NULL),
_first_all_fine_prts(NULL), _last_all_fine_prts(NULL),
_n_fine_entries(0), _n_coarse_entries(0),
--- 257,269 ----
size_t OtherRegionsTable::_max_fine_entries = 0;
size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0;
size_t OtherRegionsTable::_fine_eviction_stride = 0;
size_t OtherRegionsTable::_fine_eviction_sample_size = 0;
! OtherRegionsTable::OtherRegionsTable(HeapRegion* hr, Mutex* m) :
_g1h(G1CollectedHeap::heap()),
! _hr(hr), _m(m),
_coarse_map(G1CollectedHeap::heap()->max_regions(),
false /* in-resource-area */),
_fine_grain_regions(NULL),
_first_all_fine_prts(NULL), _last_all_fine_prts(NULL),
_n_fine_entries(0), _n_coarse_entries(0),
*** 361,381 ****
int** OtherRegionsTable::_from_card_cache = NULL;
size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
void OtherRegionsTable::init_from_card_cache(size_t max_regions) {
! _from_card_cache_max_regions = max_regions;
int n_par_rs = HeapRegionRemSet::num_par_rem_sets();
_from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC);
for (int i = 0; i < n_par_rs; i++) {
! _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, max_regions, mtGC);
! for (size_t j = 0; j < max_regions; j++) {
_from_card_cache[i][j] = -1; // An invalid value.
}
}
! _from_card_cache_mem_size = n_par_rs * max_regions * sizeof(int);
}
void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) {
for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
assert(new_n_regs <= _from_card_cache_max_regions, "Must be within max.");
--- 360,381 ----
int** OtherRegionsTable::_from_card_cache = NULL;
size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
void OtherRegionsTable::init_from_card_cache(size_t max_regions) {
! // pad rows to cache line sizes.
! _from_card_cache_max_regions = align_size_up(max_regions, DEFAULT_CACHE_LINE_SIZE / sizeof(int));
int n_par_rs = HeapRegionRemSet::num_par_rem_sets();
_from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC);
for (int i = 0; i < n_par_rs; i++) {
! _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, _from_card_cache_max_regions, mtGC);
! for (size_t j = 0; j < _from_card_cache_max_regions; j++) {
_from_card_cache[i][j] = -1; // An invalid value.
}
}
! _from_card_cache_mem_size = n_par_rs * _from_card_cache_max_regions * sizeof(int);
}
void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) {
for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
assert(new_n_regs <= _from_card_cache_max_regions, "Must be within max.");
*** 440,450 ****
// Otherwise find a per-region table to add it to.
size_t ind = from_hrs_ind & _mod_max_fine_entries_mask;
PerRegionTable* prt = find_region_table(ind, from_hr);
if (prt == NULL) {
! MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
// Confirm that it's really not there...
prt = find_region_table(ind, from_hr);
if (prt == NULL) {
uintptr_t from_hr_bot_card_index =
--- 440,450 ----
// Otherwise find a per-region table to add it to.
size_t ind = from_hrs_ind & _mod_max_fine_entries_mask;
PerRegionTable* prt = find_region_table(ind, from_hr);
if (prt == NULL) {
! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
// Confirm that it's really not there...
prt = find_region_table(ind, from_hr);
if (prt == NULL) {
uintptr_t from_hr_bot_card_index =
*** 542,552 ****
}
jint OtherRegionsTable::_n_coarsenings = 0;
PerRegionTable* OtherRegionsTable::delete_region_table() {
! assert(_m.owned_by_self(), "Precondition");
assert(_n_fine_entries == _max_fine_entries, "Precondition");
PerRegionTable* max = NULL;
jint max_occ = 0;
PerRegionTable** max_prev;
size_t max_ind;
--- 542,552 ----
}
jint OtherRegionsTable::_n_coarsenings = 0;
PerRegionTable* OtherRegionsTable::delete_region_table() {
! assert(_m->owned_by_self(), "Precondition");
assert(_n_fine_entries == _max_fine_entries, "Precondition");
PerRegionTable* max = NULL;
jint max_occ = 0;
PerRegionTable** max_prev;
size_t max_ind;
*** 674,685 ****
clear_fcc();
}
size_t OtherRegionsTable::occupied() const {
- // Cast away const in this case.
- MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
size_t sum = occ_fine();
sum += occ_sparse();
sum += occ_coarse();
return sum;
}
--- 674,683 ----
*** 705,716 ****
size_t OtherRegionsTable::occ_sparse() const {
return _sparse_table.occupied();
}
size_t OtherRegionsTable::mem_size() const {
! // Cast away const in this case.
! MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
size_t sum = 0;
// all PRTs are of the same size so it is sufficient to query only one of them.
if (_first_all_fine_prts != NULL) {
assert(_last_all_fine_prts != NULL &&
_first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
--- 703,713 ----
size_t OtherRegionsTable::occ_sparse() const {
return _sparse_table.occupied();
}
size_t OtherRegionsTable::mem_size() const {
! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
size_t sum = 0;
// all PRTs are of the same size so it is sufficient to query only one of them.
if (_first_all_fine_prts != NULL) {
assert(_last_all_fine_prts != NULL &&
_first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
*** 731,747 ****
return PerRegionTable::fl_mem_size();
}
void OtherRegionsTable::clear_fcc() {
size_t hrs_idx = hr()->hrs_index();
! for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
_from_card_cache[i][hrs_idx] = -1;
}
}
void OtherRegionsTable::clear() {
- MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
// if there are no entries, skip this step
if (_first_all_fine_prts != NULL) {
guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
--- 728,744 ----
return PerRegionTable::fl_mem_size();
}
void OtherRegionsTable::clear_fcc() {
size_t hrs_idx = hr()->hrs_index();
! uint num_par_remsets = HeapRegionRemSet::num_par_rem_sets();
! for (uint i = 0; i < num_par_remsets; i++) {
_from_card_cache[i][hrs_idx] = -1;
}
}
void OtherRegionsTable::clear() {
// if there are no entries, skip this step
if (_first_all_fine_prts != NULL) {
guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
*** 757,767 ****
clear_fcc();
}
void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) {
! MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
size_t hrs_ind = (size_t) from_hr->hrs_index();
size_t ind = hrs_ind & _mod_max_fine_entries_mask;
if (del_single_region_table(ind, from_hr)) {
assert(!_coarse_map.at(hrs_ind), "Inv");
} else {
--- 754,764 ----
clear_fcc();
}
void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) {
! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
size_t hrs_ind = (size_t) from_hr->hrs_index();
size_t ind = hrs_ind & _mod_max_fine_entries_mask;
if (del_single_region_table(ind, from_hr)) {
assert(!_coarse_map.at(hrs_ind), "Inv");
} else {
*** 802,813 ****
return false;
}
}
bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const {
! // Cast away const in this case.
! MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
return contains_reference_locked(from);
}
bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const {
HeapRegion* hr = _g1h->heap_region_containing_raw(from);
--- 799,809 ----
return false;
}
}
bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const {
! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
return contains_reference_locked(from);
}
bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const {
HeapRegion* hr = _g1h->heap_region_containing_raw(from);
*** 848,858 ****
return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
}
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
HeapRegion* hr)
! : _bosa(bosa), _strong_code_roots_list(NULL), _other_regions(hr) {
reset_for_par_iteration();
}
void HeapRegionRemSet::setup_remset_size() {
// Setup sparse and fine-grain tables sizes.
--- 844,855 ----
return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
}
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
HeapRegion* hr)
! : _bosa(bosa), _m(Mutex::leaf, "An OtherRegionsTable lock", true),
! _other_regions(hr, &_m), _code_roots() {
reset_for_par_iteration();
}
void HeapRegionRemSet::setup_remset_size() {
// Setup sparse and fine-grain tables sizes.
*** 881,891 ****
bool HeapRegionRemSet::iter_is_complete() {
return _iter_state == Complete;
}
#ifndef PRODUCT
! void HeapRegionRemSet::print() const {
HeapRegionRemSetIterator iter(this);
size_t card_index;
while (iter.has_next(card_index)) {
HeapWord* card_start =
G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
--- 878,888 ----
bool HeapRegionRemSet::iter_is_complete() {
return _iter_state == Complete;
}
#ifndef PRODUCT
! void HeapRegionRemSet::print() {
HeapRegionRemSetIterator iter(this);
size_t card_index;
while (iter.has_next(card_index)) {
HeapWord* card_start =
G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
*** 907,924 ****
void HeapRegionRemSet::cleanup() {
SparsePRT::cleanup_all();
}
void HeapRegionRemSet::clear() {
! if (_strong_code_roots_list != NULL) {
! delete _strong_code_roots_list;
! }
! _strong_code_roots_list = new (ResourceObj::C_HEAP, mtGC)
! GrowableArray<nmethod*>(10, 0, NULL, true);
_other_regions.clear();
! assert(occupied() == 0, "Should be clear.");
reset_for_par_iteration();
}
void HeapRegionRemSet::reset_for_par_iteration() {
_iter_state = Unclaimed;
--- 904,921 ----
void HeapRegionRemSet::cleanup() {
SparsePRT::cleanup_all();
}
void HeapRegionRemSet::clear() {
! MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
! clear_locked();
! }
+ void HeapRegionRemSet::clear_locked() {
+ _code_roots.clear();
_other_regions.clear();
! assert(occupied_locked() == 0, "Should be clear.");
reset_for_par_iteration();
}
void HeapRegionRemSet::reset_for_par_iteration() {
_iter_state = Unclaimed;
*** 935,960 ****
// Code roots support
void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
assert(nm != NULL, "sanity");
! // Search for the code blob from the RHS to avoid
! // duplicate entries as much as possible
! if (_strong_code_roots_list->find_from_end(nm) < 0) {
! // Code blob isn't already in the list
! _strong_code_roots_list->push(nm);
! }
}
void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) {
assert(nm != NULL, "sanity");
! int idx = _strong_code_roots_list->find(nm);
! if (idx >= 0) {
! _strong_code_roots_list->remove_at(idx);
! }
// Check that there were no duplicates
! guarantee(_strong_code_roots_list->find(nm) < 0, "duplicate entry found");
}
class NMethodMigrationOopClosure : public OopClosure {
G1CollectedHeap* _g1h;
HeapRegion* _from;
--- 932,949 ----
// Code roots support
void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
assert(nm != NULL, "sanity");
! _code_roots.add(nm);
}
void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) {
assert(nm != NULL, "sanity");
! _code_roots.remove(nm);
// Check that there were no duplicates
! guarantee(!_code_roots.contains(nm), "duplicate entry found");
}
class NMethodMigrationOopClosure : public OopClosure {
G1CollectedHeap* _g1h;
HeapRegion* _from;
*** 1012,1023 ****
// List of code blobs to retain for this region
GrowableArray<nmethod*> to_be_retained(10);
G1CollectedHeap* g1h = G1CollectedHeap::heap();
! while (_strong_code_roots_list->is_nonempty()) {
! nmethod *nm = _strong_code_roots_list->pop();
if (nm != NULL) {
NMethodMigrationOopClosure oop_cl(g1h, hr(), nm);
nm->oops_do(&oop_cl);
if (oop_cl.retain()) {
to_be_retained.push(nm);
--- 1001,1012 ----
// List of code blobs to retain for this region
GrowableArray<nmethod*> to_be_retained(10);
G1CollectedHeap* g1h = G1CollectedHeap::heap();
! while (!_code_roots.is_empty()) {
! nmethod *nm = _code_roots.pop();
if (nm != NULL) {
NMethodMigrationOopClosure oop_cl(g1h, hr(), nm);
nm->oops_do(&oop_cl);
if (oop_cl.retain()) {
to_be_retained.push(nm);
*** 1035,1059 ****
assert(nm != NULL, "sanity");
add_strong_code_root(nm);
}
}
! void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const {
! for (int i = 0; i < _strong_code_roots_list->length(); i += 1) {
! nmethod* nm = _strong_code_roots_list->at(i);
! blk->do_code_blob(nm);
! }
}
size_t HeapRegionRemSet::strong_code_roots_mem_size() {
! return sizeof(GrowableArray<nmethod*>) +
! _strong_code_roots_list->max_length() * sizeof(nmethod*);
}
//-------------------- Iteration --------------------
! HeapRegionRemSetIterator:: HeapRegionRemSetIterator(const HeapRegionRemSet* hrrs) :
_hrrs(hrrs),
_g1h(G1CollectedHeap::heap()),
_coarse_map(&hrrs->_other_regions._coarse_map),
_fine_grain_regions(hrrs->_other_regions._fine_grain_regions),
_bosa(hrrs->bosa()),
--- 1024,1044 ----
assert(nm != NULL, "sanity");
add_strong_code_root(nm);
}
}
! void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) {
! _code_roots.nmethods_do(blk);
}
size_t HeapRegionRemSet::strong_code_roots_mem_size() {
! return _code_roots.mem_size();
}
//-------------------- Iteration --------------------
! HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) :
_hrrs(hrrs),
_g1h(G1CollectedHeap::heap()),
_coarse_map(&hrrs->_other_regions._coarse_map),
_fine_grain_regions(hrrs->_other_regions._fine_grain_regions),
_bosa(hrrs->bosa()),