8242038: G1: Lazily initialize RSHashTables
Reviewed-by: kbarrett, sjohanss, tschatzl
This commit is contained in:
parent
7c351405c4
commit
cdfe841d3d
@ -85,6 +85,21 @@ void SparsePRTEntry::copy_cards(SparsePRTEntry* e) const {
|
|||||||
|
|
||||||
float RSHashTable::TableOccupancyFactor = 0.5f;
|
float RSHashTable::TableOccupancyFactor = 0.5f;
|
||||||
|
|
||||||
|
// The empty table can't hold any entries and is effectively immutable
|
||||||
|
// This means it can be used as an initial sentinel value
|
||||||
|
static int empty_buckets[] = { RSHashTable::NullEntry };
|
||||||
|
RSHashTable RSHashTable::empty_table;
|
||||||
|
|
||||||
|
RSHashTable::RSHashTable() :
|
||||||
|
_num_entries(0),
|
||||||
|
_capacity(0),
|
||||||
|
_capacity_mask(0),
|
||||||
|
_occupied_entries(0),
|
||||||
|
_entries(NULL),
|
||||||
|
_buckets(empty_buckets),
|
||||||
|
_free_region(0),
|
||||||
|
_free_list(NullEntry) { }
|
||||||
|
|
||||||
RSHashTable::RSHashTable(size_t capacity) :
|
RSHashTable::RSHashTable(size_t capacity) :
|
||||||
_num_entries((capacity * TableOccupancyFactor) + 1),
|
_num_entries((capacity * TableOccupancyFactor) + 1),
|
||||||
_capacity(capacity),
|
_capacity(capacity),
|
||||||
@ -99,14 +114,19 @@ RSHashTable::RSHashTable(size_t capacity) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
RSHashTable::~RSHashTable() {
|
RSHashTable::~RSHashTable() {
|
||||||
FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries);
|
// Nothing to free for empty RSHashTable
|
||||||
FREE_C_HEAP_ARRAY(int, _buckets);
|
if (_buckets != empty_buckets) {
|
||||||
|
assert(_entries != NULL, "invariant");
|
||||||
|
FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries);
|
||||||
|
FREE_C_HEAP_ARRAY(int, _buckets);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSHashTable::clear() {
|
void RSHashTable::clear() {
|
||||||
|
assert(_buckets != empty_buckets, "Shouldn't call this for the empty_table");
|
||||||
_occupied_entries = 0;
|
_occupied_entries = 0;
|
||||||
guarantee(_entries != NULL, "INV");
|
guarantee(_entries != NULL, "invariant");
|
||||||
guarantee(_buckets != NULL, "INV");
|
guarantee(_buckets != NULL, "invariant");
|
||||||
|
|
||||||
guarantee(_capacity <= ((size_t)1 << (sizeof(int)*BitsPerByte-1)) - 1,
|
guarantee(_capacity <= ((size_t)1 << (sizeof(int)*BitsPerByte-1)) - 1,
|
||||||
"_capacity too large");
|
"_capacity too large");
|
||||||
@ -119,6 +139,7 @@ void RSHashTable::clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SparsePRT::AddCardResult RSHashTable::add_card(RegionIdx_t region_ind, CardIdx_t card_index) {
|
SparsePRT::AddCardResult RSHashTable::add_card(RegionIdx_t region_ind, CardIdx_t card_index) {
|
||||||
|
assert(this != &empty_table, "can't add a card to the empty table");
|
||||||
SparsePRTEntry* e = entry_for_region_ind_create(region_ind);
|
SparsePRTEntry* e = entry_for_region_ind_create(region_ind);
|
||||||
assert(e != NULL && e->r_ind() == region_ind,
|
assert(e != NULL && e->r_ind() == region_ind,
|
||||||
"Postcondition of call above.");
|
"Postcondition of call above.");
|
||||||
@ -207,7 +228,7 @@ void RSHashTable::add_entry(SparsePRTEntry* e) {
|
|||||||
|
|
||||||
bool RSHashTableBucketIter::has_next(SparsePRTEntry*& entry) {
|
bool RSHashTableBucketIter::has_next(SparsePRTEntry*& entry) {
|
||||||
while (_bl_ind == RSHashTable::NullEntry) {
|
while (_bl_ind == RSHashTable::NullEntry) {
|
||||||
if (_tbl_ind == (int)_rsht->capacity() - 1) {
|
if (_tbl_ind + 1 >= _rsht->capacity()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_tbl_ind++;
|
_tbl_ind++;
|
||||||
@ -231,12 +252,14 @@ size_t RSHashTable::mem_size() const {
|
|||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
SparsePRT::SparsePRT() :
|
SparsePRT::SparsePRT() :
|
||||||
_table(new RSHashTable(InitialCapacity)) {
|
_table(&RSHashTable::empty_table) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SparsePRT::~SparsePRT() {
|
SparsePRT::~SparsePRT() {
|
||||||
delete _table;
|
if (_table != &RSHashTable::empty_table) {
|
||||||
|
delete _table;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -262,23 +285,27 @@ bool SparsePRT::delete_entry(RegionIdx_t region_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SparsePRT::clear() {
|
void SparsePRT::clear() {
|
||||||
// If the entry table is not at initial capacity, just create a new one.
|
// If the entry table not at initial capacity, just reset to the empty table.
|
||||||
if (_table->capacity() != InitialCapacity) {
|
if (_table->capacity() == InitialCapacity) {
|
||||||
delete _table;
|
|
||||||
_table = new RSHashTable(InitialCapacity);
|
|
||||||
} else {
|
|
||||||
_table->clear();
|
_table->clear();
|
||||||
|
} else if (_table != &RSHashTable::empty_table) {
|
||||||
|
delete _table;
|
||||||
|
_table = &RSHashTable::empty_table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SparsePRT::expand() {
|
void SparsePRT::expand() {
|
||||||
RSHashTable* last = _table;
|
RSHashTable* last = _table;
|
||||||
_table = new RSHashTable(last->capacity() * 2);
|
if (last != &RSHashTable::empty_table) {
|
||||||
for (size_t i = 0; i < last->num_entries(); i++) {
|
_table = new RSHashTable(last->capacity() * 2);
|
||||||
SparsePRTEntry* e = last->entry((int)i);
|
for (size_t i = 0; i < last->num_entries(); i++) {
|
||||||
if (e->valid_entry()) {
|
SparsePRTEntry* e = last->entry((int)i);
|
||||||
_table->add_entry(e);
|
if (e->valid_entry()) {
|
||||||
|
_table->add_entry(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
delete last;
|
||||||
|
} else {
|
||||||
|
_table = new RSHashTable(InitialCapacity);
|
||||||
}
|
}
|
||||||
delete last;
|
|
||||||
}
|
}
|
||||||
|
@ -173,11 +173,15 @@ class RSHashTable : public CHeapObj<mtGC> {
|
|||||||
// deleted from any bucket lists.
|
// deleted from any bucket lists.
|
||||||
void free_entry(int fi);
|
void free_entry(int fi);
|
||||||
|
|
||||||
|
// For the empty sentinel created at static initialization time
|
||||||
|
RSHashTable();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RSHashTable(size_t capacity);
|
RSHashTable(size_t capacity);
|
||||||
~RSHashTable();
|
~RSHashTable();
|
||||||
|
|
||||||
static const int NullEntry = -1;
|
static const int NullEntry = -1;
|
||||||
|
static RSHashTable empty_table;
|
||||||
|
|
||||||
bool should_expand() const { return _occupied_entries == _num_entries; }
|
bool should_expand() const { return _occupied_entries == _num_entries; }
|
||||||
|
|
||||||
@ -215,8 +219,8 @@ public:
|
|||||||
|
|
||||||
// This is embedded in HRRS iterator.
|
// This is embedded in HRRS iterator.
|
||||||
class RSHashTableBucketIter {
|
class RSHashTableBucketIter {
|
||||||
int _tbl_ind; // [-1, 0.._rsht->_capacity)
|
uint _tbl_ind; // [0.._rsht->_capacity)
|
||||||
int _bl_ind; // [-1, 0.._rsht->_capacity)
|
int _bl_ind; // [-1, 0.._rsht->_capacity)
|
||||||
|
|
||||||
RSHashTable* _rsht;
|
RSHashTable* _rsht;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user