mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-12 14:39:49 +00:00
8234328: VectorSet::clear can cause fragmentation
Reviewed-by: neliasso
This commit is contained in:
parent
5ca3e6334a
commit
40bbdf472c
@ -31,17 +31,20 @@
|
||||
|
||||
VectorSet::VectorSet(Arena *arena) : _size(2),
|
||||
_data(NEW_ARENA_ARRAY(arena, uint32_t, 2)),
|
||||
_data_size(2),
|
||||
_set_arena(arena) {
|
||||
_data[0] = 0;
|
||||
_data[1] = 0;
|
||||
}
|
||||
|
||||
// Expand the existing set to a bigger size
|
||||
void VectorSet::grow(uint new_size) {
|
||||
new_size = (new_size + bit_mask) >> word_bits;
|
||||
assert(new_size > 0, "sanity");
|
||||
uint x = next_power_of_2(new_size);
|
||||
_data = REALLOC_ARENA_ARRAY(_set_arena, uint32_t, _data, _size, x);
|
||||
void VectorSet::grow(uint new_word_capacity) {
|
||||
assert(new_word_capacity < (1U << 30), "");
|
||||
uint x = next_power_of_2(new_word_capacity);
|
||||
if (x > _data_size) {
|
||||
_data = REALLOC_ARENA_ARRAY(_set_arena, uint32_t, _data, _size, x);
|
||||
_data_size = x;
|
||||
}
|
||||
Copy::zero_to_bytes(_data + _size, (x - _size) * sizeof(uint32_t));
|
||||
_size = x;
|
||||
}
|
||||
@ -51,20 +54,11 @@ void VectorSet::insert(uint elem) {
|
||||
uint32_t word = elem >> word_bits;
|
||||
uint32_t mask = 1U << (elem & bit_mask);
|
||||
if (word >= _size) {
|
||||
grow(elem + 1);
|
||||
grow(word);
|
||||
}
|
||||
_data[word] |= mask;
|
||||
}
|
||||
|
||||
// Resets the storage
|
||||
void VectorSet::reset_memory() {
|
||||
assert(_size >= 2, "_size can never be less than 2");
|
||||
_data = REALLOC_ARENA_ARRAY(_set_arena, uint32_t, _data, _size, 2);
|
||||
_size = 2;
|
||||
_data[0] = 0;
|
||||
_data[1] = 0;
|
||||
}
|
||||
|
||||
// Return true if the set is empty
|
||||
bool VectorSet::is_empty() const {
|
||||
for (uint32_t i = 0; i < _size; i++) {
|
||||
|
||||
@ -40,12 +40,15 @@ private:
|
||||
static const uint word_bits = 5;
|
||||
static const uint bit_mask = 31;
|
||||
|
||||
uint _size; // Size of data in 32-bit words
|
||||
uint32_t* _data; // The data, bit packed
|
||||
// Used 32-bit words
|
||||
uint _size;
|
||||
uint32_t* _data;
|
||||
// Allocated words
|
||||
uint _data_size;
|
||||
Arena* _set_arena;
|
||||
|
||||
void grow(uint newsize); // Grow vector to required bitsize
|
||||
void reset_memory();
|
||||
// Grow vector to required word capacity
|
||||
void grow(uint new_word_capacity);
|
||||
public:
|
||||
VectorSet(Arena *arena);
|
||||
~VectorSet() {}
|
||||
@ -53,15 +56,10 @@ public:
|
||||
void insert(uint elem);
|
||||
bool is_empty() const;
|
||||
void reset() {
|
||||
Copy::zero_to_bytes(_data, _size * sizeof(uint32_t));
|
||||
_size = 0;
|
||||
}
|
||||
void clear() {
|
||||
// Reclaim storage if huge
|
||||
if (_size > 100) {
|
||||
reset_memory();
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
// Fast inlined "test and set". Replaces the idiom:
|
||||
@ -73,9 +71,8 @@ public:
|
||||
bool test_set(uint elem) {
|
||||
uint32_t word = elem >> word_bits;
|
||||
if (word >= _size) {
|
||||
// Then grow; set; return 0;
|
||||
this->insert(elem);
|
||||
return false;
|
||||
// Then grow
|
||||
grow(word);
|
||||
}
|
||||
uint32_t mask = 1U << (elem & bit_mask);
|
||||
uint32_t data = _data[word];
|
||||
@ -106,11 +103,10 @@ public:
|
||||
void set(uint elem) {
|
||||
uint32_t word = elem >> word_bits;
|
||||
if (word >= _size) {
|
||||
this->insert(elem);
|
||||
} else {
|
||||
uint32_t mask = 1U << (elem & bit_mask);
|
||||
_data[word] |= mask;
|
||||
grow(word);
|
||||
}
|
||||
uint32_t mask = 1U << (elem & bit_mask);
|
||||
_data[word] |= mask;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user