200
201 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
202 // With a valid range (beg <= end), this test ensures that end != 0, as
203 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
204 if (beg != end) {
205 bm_word_t mask = inverted_bit_mask_for_range(beg, end);
206 *word_addr(beg) &= mask;
207 }
208 }
209
210 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
211 assert(value == 0 || value == 1, "0 for clear, 1 for set");
212 // With a valid range (beg <= end), this test ensures that end != 0, as
213 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
214 if (beg != end) {
215 bm_word_t* pw = word_addr(beg);
216 bm_word_t w = *pw;
217 bm_word_t mr = inverted_bit_mask_for_range(beg, end);
218 bm_word_t nw = value ? (w | ~mr) : (w & mr);
219 while (true) {
220 bm_word_t res = Atomic::cmpxchg(nw, pw, w);
221 if (res == w) break;
222 w = res;
223 nw = value ? (w | ~mr) : (w & mr);
224 }
225 }
226 }
227
228 void BitMap::set_range(idx_t beg, idx_t end) {
229 verify_range(beg, end);
230
231 idx_t beg_full_word = word_index_round_up(beg);
232 idx_t end_full_word = word_index(end);
233
234 if (beg_full_word < end_full_word) {
235 // The range includes at least one full word.
236 set_range_within_word(beg, bit_index(beg_full_word));
237 set_range_of_words(beg_full_word, end_full_word);
238 set_range_within_word(bit_index(end_full_word), end);
239 } else {
240 // The range spans at most 2 partial words.
623 if (!blk->do_bit(offset)) return false;
624 // resample at each closure application
625 // (see, for instance, CMS bug 4525989)
626 rest = map(index) >> (offset & (BitsPerWord -1));
627 }
628 rest = rest >> 1;
629 }
630 }
631 return true;
632 }
633
634 const BitMap::idx_t* BitMap::_pop_count_table = NULL;
635
636 void BitMap::init_pop_count_table() {
637 if (_pop_count_table == NULL) {
638 BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256, mtInternal);
639 for (uint i = 0; i < 256; i++) {
640 table[i] = num_set_bits(i);
641 }
642
643 if (!Atomic::replace_if_null(table, &_pop_count_table)) {
644 guarantee(_pop_count_table != NULL, "invariant");
645 FREE_C_HEAP_ARRAY(idx_t, table);
646 }
647 }
648 }
649
650 BitMap::idx_t BitMap::num_set_bits(bm_word_t w) {
651 idx_t bits = 0;
652
653 while (w != 0) {
654 while ((w & 1) == 0) {
655 w >>= 1;
656 }
657 bits++;
658 w >>= 1;
659 }
660 return bits;
661 }
662
663 BitMap::idx_t BitMap::num_set_bits_from_table(unsigned char c) {
|
200
201 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
202 // With a valid range (beg <= end), this test ensures that end != 0, as
203 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
204 if (beg != end) {
205 bm_word_t mask = inverted_bit_mask_for_range(beg, end);
206 *word_addr(beg) &= mask;
207 }
208 }
209
210 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
211 assert(value == 0 || value == 1, "0 for clear, 1 for set");
212 // With a valid range (beg <= end), this test ensures that end != 0, as
213 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
214 if (beg != end) {
215 bm_word_t* pw = word_addr(beg);
216 bm_word_t w = *pw;
217 bm_word_t mr = inverted_bit_mask_for_range(beg, end);
218 bm_word_t nw = value ? (w | ~mr) : (w & mr);
219 while (true) {
220 bm_word_t res = Atomic::cmpxchg(pw, w, nw);
221 if (res == w) break;
222 w = res;
223 nw = value ? (w | ~mr) : (w & mr);
224 }
225 }
226 }
227
228 void BitMap::set_range(idx_t beg, idx_t end) {
229 verify_range(beg, end);
230
231 idx_t beg_full_word = word_index_round_up(beg);
232 idx_t end_full_word = word_index(end);
233
234 if (beg_full_word < end_full_word) {
235 // The range includes at least one full word.
236 set_range_within_word(beg, bit_index(beg_full_word));
237 set_range_of_words(beg_full_word, end_full_word);
238 set_range_within_word(bit_index(end_full_word), end);
239 } else {
240 // The range spans at most 2 partial words.
623 if (!blk->do_bit(offset)) return false;
624 // resample at each closure application
625 // (see, for instance, CMS bug 4525989)
626 rest = map(index) >> (offset & (BitsPerWord -1));
627 }
628 rest = rest >> 1;
629 }
630 }
631 return true;
632 }
633
634 const BitMap::idx_t* BitMap::_pop_count_table = NULL;
635
636 void BitMap::init_pop_count_table() {
637 if (_pop_count_table == NULL) {
638 BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256, mtInternal);
639 for (uint i = 0; i < 256; i++) {
640 table[i] = num_set_bits(i);
641 }
642
643 if (!Atomic::replace_if_null(&_pop_count_table, table)) {
644 guarantee(_pop_count_table != NULL, "invariant");
645 FREE_C_HEAP_ARRAY(idx_t, table);
646 }
647 }
648 }
649
650 BitMap::idx_t BitMap::num_set_bits(bm_word_t w) {
651 idx_t bits = 0;
652
653 while (w != 0) {
654 while ((w & 1) == 0) {
655 w >>= 1;
656 }
657 bits++;
658 w >>= 1;
659 }
660 return bits;
661 }
662
663 BitMap::idx_t BitMap::num_set_bits_from_table(unsigned char c) {
|