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