25
#include "precompiled.hpp"
26
#include "gc/shenandoah/shenandoahSimpleBitMap.hpp"
28
ShenandoahSimpleBitMap::ShenandoahSimpleBitMap(size_t num_bits) :
30
_num_words(align_up(num_bits, BitsPerWord) / BitsPerWord),
31
_bitmap(NEW_C_HEAP_ARRAY(uintx, _num_words, mtGC))
36
ShenandoahSimpleBitMap::~ShenandoahSimpleBitMap() {
37
if (_bitmap != nullptr) {
38
FREE_C_HEAP_ARRAY(uintx, _bitmap);
42
size_t ShenandoahSimpleBitMap::count_leading_ones(idx_t start_idx) const {
43
assert((start_idx >= 0) && (start_idx < _num_bits), "precondition");
44
size_t array_idx = start_idx >> LogBitsPerWord;
45
uintx element_bits = _bitmap[array_idx];
46
uintx bit_number = start_idx & right_n_bits(LogBitsPerWord);
47
uintx mask = ~right_n_bits(bit_number);
48
size_t counted_ones = 0;
49
while ((element_bits & mask) == mask) {
51
size_t found_ones = BitsPerWord - bit_number;
52
counted_ones += found_ones;
56
element_bits = _bitmap[array_idx];
64
uintx aligned = element_bits >> bit_number;
65
uintx complement = ~aligned;
66
return counted_ones + count_trailing_zeros<uintx>(complement);
69
size_t ShenandoahSimpleBitMap::count_trailing_ones(idx_t last_idx) const {
70
assert((last_idx >= 0) && (last_idx < _num_bits), "precondition");
71
size_t array_idx = last_idx >> LogBitsPerWord;
72
uintx element_bits = _bitmap[array_idx];
73
uintx bit_number = last_idx & right_n_bits(LogBitsPerWord);
75
uintx mask = right_n_bits(bit_number + 1);
76
size_t counted_ones = 0;
77
while ((element_bits & mask) == mask) {
79
size_t found_ones = bit_number + 1;
80
counted_ones += found_ones;
83
element_bits = _bitmap[array_idx];
85
bit_number = BitsPerWord - 1;
91
uintx aligned = element_bits << (BitsPerWord - (bit_number + 1));
92
uintx complement = ~aligned;
93
return counted_ones + count_leading_zeros<uintx>(complement);
96
bool ShenandoahSimpleBitMap::is_forward_consecutive_ones(idx_t start_idx, idx_t count) const {
98
assert((start_idx >= 0) && (start_idx < _num_bits), "precondition: start_idx: " SSIZE_FORMAT ", count: " SSIZE_FORMAT,
100
assert(start_idx + count <= (idx_t) _num_bits, "precondition");
101
size_t array_idx = start_idx >> LogBitsPerWord;
102
uintx bit_number = start_idx & right_n_bits(LogBitsPerWord);
103
uintx element_bits = _bitmap[array_idx];
104
uintx bits_to_examine = BitsPerWord - bit_number;
105
element_bits >>= bit_number;
106
uintx complement = ~element_bits;
108
if (complement != 0) {
109
trailing_ones = count_trailing_zeros<uintx>(complement);
111
trailing_ones = bits_to_examine;
113
if (trailing_ones >= (uintx) count) {
115
} else if (trailing_ones == bits_to_examine) {
116
start_idx += bits_to_examine;
117
count -= bits_to_examine;
126
bool ShenandoahSimpleBitMap::is_backward_consecutive_ones(idx_t last_idx, idx_t count) const {
128
assert((last_idx >= 0) && (last_idx < _num_bits), "precondition");
129
assert(last_idx - count >= -1, "precondition");
130
size_t array_idx = last_idx >> LogBitsPerWord;
131
uintx bit_number = last_idx & right_n_bits(LogBitsPerWord);
132
uintx element_bits = _bitmap[array_idx];
133
uintx bits_to_examine = bit_number + 1;
134
element_bits <<= (BitsPerWord - bits_to_examine);
135
uintx complement = ~element_bits;
137
if (complement != 0) {
138
leading_ones = count_leading_zeros<uintx>(complement);
140
leading_ones = bits_to_examine;
142
if (leading_ones >= (uintx) count) {
144
} else if (leading_ones == bits_to_examine) {
145
last_idx -= leading_ones;
146
count -= leading_ones;
155
idx_t ShenandoahSimpleBitMap::find_first_consecutive_set_bits(idx_t beg, idx_t end, size_t num_bits) const {
156
assert((beg >= 0) && (beg < _num_bits), "precondition");
159
idx_t start_boundary = end - num_bits;
160
if (beg > start_boundary) {
163
uintx array_idx = beg >> LogBitsPerWord;
164
uintx bit_number = beg & right_n_bits(LogBitsPerWord);
165
uintx element_bits = _bitmap[array_idx];
166
if (bit_number > 0) {
167
uintx mask_out = right_n_bits(bit_number);
168
element_bits &= ~mask_out;
195
if (element_bits == 0) {
197
beg += BitsPerWord - bit_number;
198
if (beg > start_boundary) {
204
element_bits = _bitmap[array_idx];
205
} else if (is_forward_consecutive_ones(beg, num_bits)) {
210
uintx next_set_bit = count_trailing_zeros<uintx>(element_bits);
211
uintx next_start_candidate_1 = (array_idx << LogBitsPerWord) + next_set_bit;
215
size_t trailing_ones = count_trailing_ones(beg + num_bits - 1);
216
uintx next_start_candidate_2 = beg + num_bits - trailing_ones;
218
beg = MAX2(next_start_candidate_1, next_start_candidate_2);
219
if (beg > start_boundary) {
223
array_idx = beg >> LogBitsPerWord;
224
element_bits = _bitmap[array_idx];
225
bit_number = beg & right_n_bits(LogBitsPerWord);
226
if (bit_number > 0) {
227
size_t mask_out = right_n_bits(bit_number);
228
element_bits &= ~mask_out;
234
idx_t ShenandoahSimpleBitMap::find_last_consecutive_set_bits(const idx_t beg, idx_t end, const size_t num_bits) const {
236
assert((end >= 0) && (end < _num_bits), "precondition");
239
idx_t last_boundary = beg + num_bits;
240
if (end < last_boundary) {
244
size_t array_idx = end >> LogBitsPerWord;
245
uintx bit_number = end & right_n_bits(LogBitsPerWord);
246
uintx element_bits = _bitmap[array_idx];
247
if (bit_number < BitsPerWord - 1) {
248
uintx mask_in = right_n_bits(bit_number + 1);
249
element_bits &= mask_in;
254
if (element_bits == 0) {
256
end -= bit_number + 1;
257
if (end < last_boundary) {
262
bit_number = BitsPerWord - 1;
263
element_bits = _bitmap[array_idx];
264
} else if (is_backward_consecutive_ones(end, num_bits)) {
265
return end + 1 - num_bits;
269
uintx next_set_bit = BitsPerWord - (1 + count_leading_zeros<uintx>(element_bits));
270
uintx next_last_candidate_1 = (array_idx << LogBitsPerWord) + next_set_bit;
274
size_t leading_ones = count_leading_ones(end - (num_bits - 1));
275
uintx next_last_candidate_2 = end - (num_bits - leading_ones);
277
end = MIN2(next_last_candidate_1, next_last_candidate_2);
278
if (end < last_boundary) {
282
array_idx = end >> LogBitsPerWord;
283
bit_number = end & right_n_bits(LogBitsPerWord);
284
element_bits = _bitmap[array_idx];
285
if (bit_number < BitsPerWord - 1){
286
size_t mask_in = right_n_bits(bit_number + 1);
287
element_bits &= mask_in;