--- a/src/hotspot/share/opto/indexSet.hpp Thu Nov 14 10:55:46 2019 +0100
+++ b/src/hotspot/share/opto/indexSet.hpp Thu Nov 14 15:24:35 2019 +0100
@@ -190,6 +190,9 @@
// The number of elements in the set
uint _count;
+ // The current upper limit of blocks that has been allocated and might be in use
+ uint _current_block_limit;
+
// Our top level array of bitvector segments
BitBlock **_blocks;
@@ -246,12 +249,13 @@
void clear() {
_count = 0;
- for (uint i = 0; i < _max_blocks; i++) {
+ for (uint i = 0; i < _current_block_limit; i++) {
BitBlock *block = _blocks[i];
if (block != &_empty_block) {
free_block(i);
}
}
+ _current_block_limit = 0;
}
uint count() const { return _count; }
@@ -380,18 +384,18 @@
// The index of the next word we will inspect
uint _next_word;
- // A pointer to the contents of the current block
- uint32_t *_words;
-
// The index of the next block we will inspect
uint _next_block;
+ // The number of blocks in the set
+ uint _max_blocks;
+
+ // A pointer to the contents of the current block
+ uint32_t *_words;
+
// A pointer to the blocks in our set
IndexSet::BitBlock **_blocks;
- // The number of blocks in the set
- uint _max_blocks;
-
// If the iterator was created from a non-const set, we replace
// non-canonical empty blocks with the _empty_block pointer. If
// _set is NULL, we do no replacement.
@@ -405,22 +409,64 @@
// If an iterator is built from a constant set then empty blocks
// are not canonicalized.
- IndexSetIterator(IndexSet *set);
- IndexSetIterator(const IndexSet *set);
+ IndexSetIterator(IndexSet *set) :
+ _current(0),
+ _value(0),
+ _next_word(IndexSet::words_per_block),
+ _next_block(0),
+ _max_blocks(set->is_empty() ? 0 : set->_current_block_limit),
+ _words(NULL),
+ _blocks(set->_blocks),
+ _set(set) {
+ #ifdef ASSERT
+ if (CollectIndexSetStatistics) {
+ set->tally_iteration_statistics();
+ }
+ set->check_watch("traversed", set->count());
+ #endif
+ }
+
+ IndexSetIterator(const IndexSet *set) :
+ _current(0),
+ _value(0),
+ _next_word(IndexSet::words_per_block),
+ _next_block(0),
+ _max_blocks(set->is_empty() ? 0 : set->_current_block_limit),
+ _words(NULL),
+ _blocks(set->_blocks),
+ _set(NULL)
+ {
+ #ifdef ASSERT
+ if (CollectIndexSetStatistics) {
+ set->tally_iteration_statistics();
+ }
+ // We don't call check_watch from here to avoid bad recursion.
+ // set->check_watch("traversed const", set->count());
+ #endif
+ }
+
+ // Return the next element of the set.
+ uint next_value() {
+ uint current = _current;
+ assert(current != 0, "sanity");
+ uint advance = count_trailing_zeros(current);
+ assert(((current >> advance) & 0x1) == 1, "sanity");
+ _current = (current >> advance) - 1;
+ _value += advance;
+ return _value;
+ }
// Return the next element of the set. Return 0 when done.
uint next() {
- uint current = _current;
- if (current != 0) {
- uint advance = count_trailing_zeros(current);
- assert(((current >> advance) & 0x1) == 1, "sanity");
- _current = (current >> advance) - 1;
- _value += advance;
- return _value;
+ if (_current != 0) {
+ return next_value();
+ } else if (_next_word < IndexSet::words_per_block || _next_block < _max_blocks) {
+ return advance_and_next();
} else {
- return advance_and_next();
+ return 0;
}
}
+
};
#endif // SHARE_OPTO_INDEXSET_HPP