comparison src/share/vm/utilities/bitMap.cpp @ 342:37f87013dfd8

6711316: Open source the Garbage-First garbage collector Summary: First mercurial integration of the code for the Garbage-First garbage collector. Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
author ysr
date Thu, 05 Jun 2008 15:57:56 -0700
parents a61af66fc99e
children 6e2afda171db
comparison
equal deleted inserted replaced
189:0b27f3512f9e 342:37f87013dfd8
24 24
25 # include "incls/_precompiled.incl" 25 # include "incls/_precompiled.incl"
26 # include "incls/_bitMap.cpp.incl" 26 # include "incls/_bitMap.cpp.incl"
27 27
28 28
29 BitMap::BitMap(idx_t* map, idx_t size_in_bits) { 29 BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
30 _map(map), _size(size_in_bits)
31 {
32 assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
30 assert(size_in_bits >= 0, "just checking"); 33 assert(size_in_bits >= 0, "just checking");
31 _map = map; 34 }
35
36
37 BitMap::BitMap(idx_t size_in_bits, bool in_resource_area) :
38 _map(NULL), _size(0)
39 {
40 assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
41 resize(size_in_bits, in_resource_area);
42 }
43
44
45 void BitMap::verify_index(idx_t index) const {
46 assert(index < _size, "BitMap index out of bounds");
47 }
48
49 void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
50 #ifdef ASSERT
51 assert(beg_index <= end_index, "BitMap range error");
52 // Note that [0,0) and [size,size) are both valid ranges.
53 if (end_index != _size) verify_index(end_index);
54 #endif
55 }
56
57 void BitMap::resize(idx_t size_in_bits, bool in_resource_area) {
58 assert(size_in_bits >= 0, "just checking");
59 idx_t old_size_in_words = size_in_words();
60 bm_word_t* old_map = map();
61
32 _size = size_in_bits; 62 _size = size_in_bits;
33 } 63 idx_t new_size_in_words = size_in_words();
34 64 if (in_resource_area) {
35 65 _map = NEW_RESOURCE_ARRAY(bm_word_t, new_size_in_words);
36 BitMap::BitMap(idx_t size_in_bits) { 66 } else {
37 assert(size_in_bits >= 0, "just checking"); 67 if (old_map != NULL) FREE_C_HEAP_ARRAY(bm_word_t, _map);
38 _size = size_in_bits; 68 _map = NEW_C_HEAP_ARRAY(bm_word_t, new_size_in_words);
39 _map = NEW_RESOURCE_ARRAY(idx_t, size_in_words()); 69 }
40 } 70 Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map,
41 71 MIN2(old_size_in_words, new_size_in_words));
42
43 void BitMap::resize(idx_t size_in_bits) {
44 assert(size_in_bits >= 0, "just checking");
45 size_t old_size_in_words = size_in_words();
46 uintptr_t* old_map = map();
47 _size = size_in_bits;
48 size_t new_size_in_words = size_in_words();
49 _map = NEW_RESOURCE_ARRAY(idx_t, new_size_in_words);
50 Copy::disjoint_words((HeapWord*) old_map, (HeapWord*) _map, MIN2(old_size_in_words, new_size_in_words));
51 if (new_size_in_words > old_size_in_words) { 72 if (new_size_in_words > old_size_in_words) {
52 clear_range_of_words(old_size_in_words, size_in_words()); 73 clear_range_of_words(old_size_in_words, size_in_words());
53 } 74 }
54 }
55
56 // Returns a bit mask for a range of bits [beg, end) within a single word. Each
57 // bit in the mask is 0 if the bit is in the range, 1 if not in the range. The
58 // returned mask can be used directly to clear the range, or inverted to set the
59 // range. Note: end must not be 0.
60 inline BitMap::idx_t
61 BitMap::inverted_bit_mask_for_range(idx_t beg, idx_t end) const {
62 assert(end != 0, "does not work when end == 0");
63 assert(beg == end || word_index(beg) == word_index(end - 1),
64 "must be a single-word range");
65 idx_t mask = bit_mask(beg) - 1; // low (right) bits
66 if (bit_in_word(end) != 0) {
67 mask |= ~(bit_mask(end) - 1); // high (left) bits
68 }
69 return mask;
70 } 75 }
71 76
72 void BitMap::set_range_within_word(idx_t beg, idx_t end) { 77 void BitMap::set_range_within_word(idx_t beg, idx_t end) {
73 // With a valid range (beg <= end), this test ensures that end != 0, as 78 // With a valid range (beg <= end), this test ensures that end != 0, as
74 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write. 79 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
75 if (beg != end) { 80 if (beg != end) {
76 idx_t mask = inverted_bit_mask_for_range(beg, end); 81 bm_word_t mask = inverted_bit_mask_for_range(beg, end);
77 *word_addr(beg) |= ~mask; 82 *word_addr(beg) |= ~mask;
78 } 83 }
79 } 84 }
80 85
81 void BitMap::clear_range_within_word(idx_t beg, idx_t end) { 86 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
82 // With a valid range (beg <= end), this test ensures that end != 0, as 87 // With a valid range (beg <= end), this test ensures that end != 0, as
83 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write. 88 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
84 if (beg != end) { 89 if (beg != end) {
85 idx_t mask = inverted_bit_mask_for_range(beg, end); 90 bm_word_t mask = inverted_bit_mask_for_range(beg, end);
86 *word_addr(beg) &= mask; 91 *word_addr(beg) &= mask;
87 } 92 }
88 } 93 }
89 94
90 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) { 95 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
103 nw = value ? (w | ~mr) : (w & mr); 108 nw = value ? (w | ~mr) : (w & mr);
104 } 109 }
105 } 110 }
106 } 111 }
107 112
108 inline void BitMap::set_large_range_of_words(idx_t beg, idx_t end) {
109 memset(_map + beg, ~(unsigned char)0, (end - beg) * sizeof(uintptr_t));
110 }
111
112 inline void BitMap::clear_large_range_of_words(idx_t beg, idx_t end) {
113 memset(_map + beg, 0, (end - beg) * sizeof(uintptr_t));
114 }
115
116 inline BitMap::idx_t BitMap::word_index_round_up(idx_t bit) const {
117 idx_t bit_rounded_up = bit + (BitsPerWord - 1);
118 // Check for integer arithmetic overflow.
119 return bit_rounded_up > bit ? word_index(bit_rounded_up) : size_in_words();
120 }
121
122 void BitMap::set_range(idx_t beg, idx_t end) { 113 void BitMap::set_range(idx_t beg, idx_t end) {
123 verify_range(beg, end); 114 verify_range(beg, end);
124 115
125 idx_t beg_full_word = word_index_round_up(beg); 116 idx_t beg_full_word = word_index_round_up(beg);
126 idx_t end_full_word = word_index(end); 117 idx_t end_full_word = word_index(end);
183 174
184 // The range includes at least one full word. 175 // The range includes at least one full word.
185 clear_range_within_word(beg, bit_index(beg_full_word)); 176 clear_range_within_word(beg, bit_index(beg_full_word));
186 clear_large_range_of_words(beg_full_word, end_full_word); 177 clear_large_range_of_words(beg_full_word, end_full_word);
187 clear_range_within_word(bit_index(end_full_word), end); 178 clear_range_within_word(bit_index(end_full_word), end);
179 }
180
181 void BitMap::mostly_disjoint_range_union(BitMap* from_bitmap,
182 idx_t from_start_index,
183 idx_t to_start_index,
184 size_t word_num) {
185 // Ensure that the parameters are correct.
186 // These shouldn't be that expensive to check, hence I left them as
187 // guarantees.
188 guarantee(from_bitmap->bit_in_word(from_start_index) == 0,
189 "it should be aligned on a word boundary");
190 guarantee(bit_in_word(to_start_index) == 0,
191 "it should be aligned on a word boundary");
192 guarantee(word_num >= 2, "word_num should be at least 2");
193
194 intptr_t* from = (intptr_t*) from_bitmap->word_addr(from_start_index);
195 intptr_t* to = (intptr_t*) word_addr(to_start_index);
196
197 if (*from != 0) {
198 // if it's 0, then there's no point in doing the CAS
199 while (true) {
200 intptr_t old_value = *to;
201 intptr_t new_value = old_value | *from;
202 intptr_t res = Atomic::cmpxchg_ptr(new_value, to, old_value);
203 if (res == old_value) break;
204 }
205 }
206 ++from;
207 ++to;
208
209 for (size_t i = 0; i < word_num - 2; ++i) {
210 if (*from != 0) {
211 // if it's 0, then there's no point in doing the CAS
212 assert(*to == 0, "nobody else should be writing here");
213 intptr_t new_value = *from;
214 *to = new_value;
215 }
216
217 ++from;
218 ++to;
219 }
220
221 if (*from != 0) {
222 // if it's 0, then there's no point in doing the CAS
223 while (true) {
224 intptr_t old_value = *to;
225 intptr_t new_value = old_value | *from;
226 intptr_t res = Atomic::cmpxchg_ptr(new_value, to, old_value);
227 if (res == old_value) break;
228 }
229 }
230
231 // the -1 is because we didn't advance them after the final CAS
232 assert(from ==
233 (intptr_t*) from_bitmap->word_addr(from_start_index) + word_num - 1,
234 "invariant");
235 assert(to == (intptr_t*) word_addr(to_start_index) + word_num - 1,
236 "invariant");
188 } 237 }
189 238
190 void BitMap::at_put(idx_t offset, bool value) { 239 void BitMap::at_put(idx_t offset, bool value) {
191 if (value) { 240 if (value) {
192 set_bit(offset); 241 set_bit(offset);
280 par_put_range_within_word(bit_index(end_full_word), end, value); 329 par_put_range_within_word(bit_index(end_full_word), end, value);
281 } 330 }
282 331
283 bool BitMap::contains(const BitMap other) const { 332 bool BitMap::contains(const BitMap other) const {
284 assert(size() == other.size(), "must have same size"); 333 assert(size() == other.size(), "must have same size");
285 uintptr_t* dest_map = map(); 334 bm_word_t* dest_map = map();
286 uintptr_t* other_map = other.map(); 335 bm_word_t* other_map = other.map();
287 idx_t size = size_in_words(); 336 idx_t size = size_in_words();
288 for (idx_t index = 0; index < size_in_words(); index++) { 337 for (idx_t index = 0; index < size_in_words(); index++) {
289 uintptr_t word_union = dest_map[index] | other_map[index]; 338 bm_word_t word_union = dest_map[index] | other_map[index];
290 // If this has more bits set than dest_map[index], then other is not a 339 // If this has more bits set than dest_map[index], then other is not a
291 // subset. 340 // subset.
292 if (word_union != dest_map[index]) return false; 341 if (word_union != dest_map[index]) return false;
293 } 342 }
294 return true; 343 return true;
295 } 344 }
296 345
297 bool BitMap::intersects(const BitMap other) const { 346 bool BitMap::intersects(const BitMap other) const {
298 assert(size() == other.size(), "must have same size"); 347 assert(size() == other.size(), "must have same size");
299 uintptr_t* dest_map = map(); 348 bm_word_t* dest_map = map();
300 uintptr_t* other_map = other.map(); 349 bm_word_t* other_map = other.map();
301 idx_t size = size_in_words(); 350 idx_t size = size_in_words();
302 for (idx_t index = 0; index < size_in_words(); index++) { 351 for (idx_t index = 0; index < size_in_words(); index++) {
303 if ((dest_map[index] & other_map[index]) != 0) return true; 352 if ((dest_map[index] & other_map[index]) != 0) return true;
304 } 353 }
305 // Otherwise, no intersection. 354 // Otherwise, no intersection.
306 return false; 355 return false;
307 } 356 }
308 357
309 void BitMap::set_union(BitMap other) { 358 void BitMap::set_union(BitMap other) {
310 assert(size() == other.size(), "must have same size"); 359 assert(size() == other.size(), "must have same size");
311 idx_t* dest_map = map(); 360 bm_word_t* dest_map = map();
312 idx_t* other_map = other.map(); 361 bm_word_t* other_map = other.map();
313 idx_t size = size_in_words(); 362 idx_t size = size_in_words();
314 for (idx_t index = 0; index < size_in_words(); index++) { 363 for (idx_t index = 0; index < size_in_words(); index++) {
315 dest_map[index] = dest_map[index] | other_map[index]; 364 dest_map[index] = dest_map[index] | other_map[index];
316 } 365 }
317 } 366 }
318 367
319 368
320 void BitMap::set_difference(BitMap other) { 369 void BitMap::set_difference(BitMap other) {
321 assert(size() == other.size(), "must have same size"); 370 assert(size() == other.size(), "must have same size");
322 idx_t* dest_map = map(); 371 bm_word_t* dest_map = map();
323 idx_t* other_map = other.map(); 372 bm_word_t* other_map = other.map();
324 idx_t size = size_in_words(); 373 idx_t size = size_in_words();
325 for (idx_t index = 0; index < size_in_words(); index++) { 374 for (idx_t index = 0; index < size_in_words(); index++) {
326 dest_map[index] = dest_map[index] & ~(other_map[index]); 375 dest_map[index] = dest_map[index] & ~(other_map[index]);
327 } 376 }
328 } 377 }
329 378
330 379
331 void BitMap::set_intersection(BitMap other) { 380 void BitMap::set_intersection(BitMap other) {
332 assert(size() == other.size(), "must have same size"); 381 assert(size() == other.size(), "must have same size");
333 idx_t* dest_map = map(); 382 bm_word_t* dest_map = map();
334 idx_t* other_map = other.map(); 383 bm_word_t* other_map = other.map();
335 idx_t size = size_in_words(); 384 idx_t size = size_in_words();
336 for (idx_t index = 0; index < size; index++) { 385 for (idx_t index = 0; index < size; index++) {
337 dest_map[index] = dest_map[index] & other_map[index]; 386 dest_map[index] = dest_map[index] & other_map[index];
338 } 387 }
339 } 388 }
340 389
341 390
391 void BitMap::set_intersection_at_offset(BitMap other, idx_t offset) {
392 assert(other.size() >= offset, "offset not in range");
393 assert(other.size() - offset >= size(), "other not large enough");
394 // XXX Ideally, we would remove this restriction.
395 guarantee((offset % (sizeof(bm_word_t) * BitsPerByte)) == 0,
396 "Only handle aligned cases so far.");
397 bm_word_t* dest_map = map();
398 bm_word_t* other_map = other.map();
399 idx_t offset_word_ind = word_index(offset);
400 idx_t size = size_in_words();
401 for (idx_t index = 0; index < size; index++) {
402 dest_map[index] = dest_map[index] & other_map[offset_word_ind + index];
403 }
404 }
405
342 bool BitMap::set_union_with_result(BitMap other) { 406 bool BitMap::set_union_with_result(BitMap other) {
343 assert(size() == other.size(), "must have same size"); 407 assert(size() == other.size(), "must have same size");
344 bool changed = false; 408 bool changed = false;
345 idx_t* dest_map = map(); 409 bm_word_t* dest_map = map();
346 idx_t* other_map = other.map(); 410 bm_word_t* other_map = other.map();
347 idx_t size = size_in_words(); 411 idx_t size = size_in_words();
348 for (idx_t index = 0; index < size; index++) { 412 for (idx_t index = 0; index < size; index++) {
349 idx_t temp = map(index) | other_map[index]; 413 idx_t temp = map(index) | other_map[index];
350 changed = changed || (temp != map(index)); 414 changed = changed || (temp != map(index));
351 map()[index] = temp; 415 map()[index] = temp;
355 419
356 420
357 bool BitMap::set_difference_with_result(BitMap other) { 421 bool BitMap::set_difference_with_result(BitMap other) {
358 assert(size() == other.size(), "must have same size"); 422 assert(size() == other.size(), "must have same size");
359 bool changed = false; 423 bool changed = false;
360 idx_t* dest_map = map(); 424 bm_word_t* dest_map = map();
361 idx_t* other_map = other.map(); 425 bm_word_t* other_map = other.map();
362 idx_t size = size_in_words(); 426 idx_t size = size_in_words();
363 for (idx_t index = 0; index < size; index++) { 427 for (idx_t index = 0; index < size; index++) {
364 idx_t temp = dest_map[index] & ~(other_map[index]); 428 bm_word_t temp = dest_map[index] & ~(other_map[index]);
365 changed = changed || (temp != dest_map[index]); 429 changed = changed || (temp != dest_map[index]);
366 dest_map[index] = temp; 430 dest_map[index] = temp;
367 } 431 }
368 return changed; 432 return changed;
369 } 433 }
370 434
371 435
372 bool BitMap::set_intersection_with_result(BitMap other) { 436 bool BitMap::set_intersection_with_result(BitMap other) {
373 assert(size() == other.size(), "must have same size"); 437 assert(size() == other.size(), "must have same size");
374 bool changed = false; 438 bool changed = false;
375 idx_t* dest_map = map(); 439 bm_word_t* dest_map = map();
376 idx_t* other_map = other.map(); 440 bm_word_t* other_map = other.map();
377 idx_t size = size_in_words(); 441 idx_t size = size_in_words();
378 for (idx_t index = 0; index < size; index++) { 442 for (idx_t index = 0; index < size; index++) {
379 idx_t orig = dest_map[index]; 443 bm_word_t orig = dest_map[index];
380 idx_t temp = orig & other_map[index]; 444 bm_word_t temp = orig & other_map[index];
381 changed = changed || (temp != orig); 445 changed = changed || (temp != orig);
382 dest_map[index] = temp; 446 dest_map[index] = temp;
383 } 447 }
384 return changed; 448 return changed;
385 } 449 }
386 450
387 451
388 void BitMap::set_from(BitMap other) { 452 void BitMap::set_from(BitMap other) {
389 assert(size() == other.size(), "must have same size"); 453 assert(size() == other.size(), "must have same size");
390 idx_t* dest_map = map(); 454 bm_word_t* dest_map = map();
391 idx_t* other_map = other.map(); 455 bm_word_t* other_map = other.map();
392 idx_t size = size_in_words(); 456 idx_t size = size_in_words();
393 for (idx_t index = 0; index < size; index++) { 457 for (idx_t index = 0; index < size; index++) {
394 dest_map[index] = other_map[index]; 458 dest_map[index] = other_map[index];
395 } 459 }
396 } 460 }
397 461
398 462
399 bool BitMap::is_same(BitMap other) { 463 bool BitMap::is_same(BitMap other) {
400 assert(size() == other.size(), "must have same size"); 464 assert(size() == other.size(), "must have same size");
401 idx_t* dest_map = map(); 465 bm_word_t* dest_map = map();
402 idx_t* other_map = other.map(); 466 bm_word_t* other_map = other.map();
403 idx_t size = size_in_words(); 467 idx_t size = size_in_words();
404 for (idx_t index = 0; index < size; index++) { 468 for (idx_t index = 0; index < size; index++) {
405 if (dest_map[index] != other_map[index]) return false; 469 if (dest_map[index] != other_map[index]) return false;
406 } 470 }
407 return true; 471 return true;
408 } 472 }
409 473
410 bool BitMap::is_full() const { 474 bool BitMap::is_full() const {
411 uintptr_t* word = map(); 475 bm_word_t* word = map();
412 idx_t rest = size(); 476 idx_t rest = size();
413 for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) { 477 for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) {
414 if (*word != (uintptr_t) AllBits) return false; 478 if (*word != (bm_word_t) AllBits) return false;
415 word++; 479 word++;
416 } 480 }
417 return rest == 0 || (*word | ~right_n_bits((int)rest)) == (uintptr_t) AllBits; 481 return rest == 0 || (*word | ~right_n_bits((int)rest)) == (bm_word_t) AllBits;
418 } 482 }
419 483
420 484
421 bool BitMap::is_empty() const { 485 bool BitMap::is_empty() const {
422 uintptr_t* word = map(); 486 bm_word_t* word = map();
423 idx_t rest = size(); 487 idx_t rest = size();
424 for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) { 488 for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) {
425 if (*word != (uintptr_t) NoBits) return false; 489 if (*word != (bm_word_t) NoBits) return false;
426 word++; 490 word++;
427 } 491 }
428 return rest == 0 || (*word & right_n_bits((int)rest)) == (uintptr_t) NoBits; 492 return rest == 0 || (*word & right_n_bits((int)rest)) == (bm_word_t) NoBits;
429 } 493 }
430 494
431 void BitMap::clear_large() { 495 void BitMap::clear_large() {
432 clear_large_range_of_words(0, size_in_words()); 496 clear_large_range_of_words(0, size_in_words());
433 } 497 }
434 498
435 // Note that if the closure itself modifies the bitmap 499 // Note that if the closure itself modifies the bitmap
436 // then modifications in and to the left of the _bit_ being 500 // then modifications in and to the left of the _bit_ being
437 // currently sampled will not be seen. Note also that the 501 // currently sampled will not be seen. Note also that the
438 // interval [leftOffset, rightOffset) is right open. 502 // interval [leftOffset, rightOffset) is right open.
439 void BitMap::iterate(BitMapClosure* blk, idx_t leftOffset, idx_t rightOffset) { 503 bool BitMap::iterate(BitMapClosure* blk, idx_t leftOffset, idx_t rightOffset) {
440 verify_range(leftOffset, rightOffset); 504 verify_range(leftOffset, rightOffset);
441 505
442 idx_t startIndex = word_index(leftOffset); 506 idx_t startIndex = word_index(leftOffset);
443 idx_t endIndex = MIN2(word_index(rightOffset) + 1, size_in_words()); 507 idx_t endIndex = MIN2(word_index(rightOffset) + 1, size_in_words());
444 for (idx_t index = startIndex, offset = leftOffset; 508 for (idx_t index = startIndex, offset = leftOffset;
445 offset < rightOffset && index < endIndex; 509 offset < rightOffset && index < endIndex;
446 offset = (++index) << LogBitsPerWord) { 510 offset = (++index) << LogBitsPerWord) {
447 idx_t rest = map(index) >> (offset & (BitsPerWord - 1)); 511 idx_t rest = map(index) >> (offset & (BitsPerWord - 1));
448 for (; offset < rightOffset && rest != (uintptr_t)NoBits; offset++) { 512 for (; offset < rightOffset && rest != (bm_word_t)NoBits; offset++) {
449 if (rest & 1) { 513 if (rest & 1) {
450 blk->do_bit(offset); 514 if (!blk->do_bit(offset)) return false;
451 // resample at each closure application 515 // resample at each closure application
452 // (see, for instance, CMS bug 4525989) 516 // (see, for instance, CMS bug 4525989)
453 rest = map(index) >> (offset & (BitsPerWord -1)); 517 rest = map(index) >> (offset & (BitsPerWord -1));
454 // XXX debugging: remove
455 // The following assertion assumes that closure application
456 // doesn't clear bits (may not be true in general, e.g. G1).
457 assert(rest & 1,
458 "incorrect shift or closure application can clear bits?");
459 } 518 }
460 rest = rest >> 1; 519 rest = rest >> 1;
461 } 520 }
462 } 521 }
463 } 522 return true;
464 523 }
465 BitMap::idx_t BitMap::get_next_one_offset(idx_t l_offset, 524
466 idx_t r_offset) const { 525 BitMap::idx_t* BitMap::_pop_count_table = NULL;
467 assert(l_offset <= size(), "BitMap index out of bounds"); 526
468 assert(r_offset <= size(), "BitMap index out of bounds"); 527 void BitMap::init_pop_count_table() {
469 assert(l_offset <= r_offset, "l_offset > r_offset ?"); 528 if (_pop_count_table == NULL) {
470 529 BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256);
471 if (l_offset == r_offset) { 530 for (uint i = 0; i < 256; i++) {
472 return l_offset; 531 table[i] = num_set_bits(i);
473 } 532 }
474 idx_t index = word_index(l_offset); 533
475 idx_t r_index = word_index(r_offset-1) + 1; 534 intptr_t res = Atomic::cmpxchg_ptr((intptr_t) table,
476 idx_t res_offset = l_offset; 535 (intptr_t*) &_pop_count_table,
477 536 (intptr_t) NULL_WORD);
478 // check bits including and to the _left_ of offset's position 537 if (res != NULL_WORD) {
479 idx_t pos = bit_in_word(res_offset); 538 guarantee( _pop_count_table == (void*) res, "invariant" );
480 idx_t res = map(index) >> pos; 539 FREE_C_HEAP_ARRAY(bm_word_t, table);
481 if (res != (uintptr_t)NoBits) { 540 }
482 // find the position of the 1-bit 541 }
483 for (; !(res & 1); res_offset++) { 542 }
484 res = res >> 1; 543
485 } 544 BitMap::idx_t BitMap::num_set_bits(bm_word_t w) {
486 assert(res_offset >= l_offset, "just checking"); 545 idx_t bits = 0;
487 return MIN2(res_offset, r_offset); 546
488 } 547 while (w != 0) {
489 // skip over all word length 0-bit runs 548 while ((w & 1) == 0) {
490 for (index++; index < r_index; index++) { 549 w >>= 1;
491 res = map(index); 550 }
492 if (res != (uintptr_t)NoBits) { 551 bits++;
493 // found a 1, return the offset 552 w >>= 1;
494 for (res_offset = index << LogBitsPerWord; !(res & 1); 553 }
495 res_offset++) { 554 return bits;
496 res = res >> 1; 555 }
497 } 556
498 assert(res & 1, "tautology; see loop condition"); 557 BitMap::idx_t BitMap::num_set_bits_from_table(unsigned char c) {
499 assert(res_offset >= l_offset, "just checking"); 558 assert(_pop_count_table != NULL, "precondition");
500 return MIN2(res_offset, r_offset); 559 return _pop_count_table[c];
501 } 560 }
502 } 561
503 return r_offset; 562 BitMap::idx_t BitMap::count_one_bits() const {
504 } 563 init_pop_count_table(); // If necessary.
505 564 idx_t sum = 0;
506 BitMap::idx_t BitMap::get_next_zero_offset(idx_t l_offset, 565 typedef unsigned char uchar;
507 idx_t r_offset) const { 566 for (idx_t i = 0; i < size_in_words(); i++) {
508 assert(l_offset <= size(), "BitMap index out of bounds"); 567 bm_word_t w = map()[i];
509 assert(r_offset <= size(), "BitMap index out of bounds"); 568 for (size_t j = 0; j < sizeof(bm_word_t); j++) {
510 assert(l_offset <= r_offset, "l_offset > r_offset ?"); 569 sum += num_set_bits_from_table(uchar(w & 255));
511 570 w >>= 8;
512 if (l_offset == r_offset) { 571 }
513 return l_offset; 572 }
514 } 573 return sum;
515 idx_t index = word_index(l_offset); 574 }
516 idx_t r_index = word_index(r_offset-1) + 1; 575
517 idx_t res_offset = l_offset;
518
519 // check bits including and to the _left_ of offset's position
520 idx_t pos = res_offset & (BitsPerWord - 1);
521 idx_t res = (map(index) >> pos) | left_n_bits((int)pos);
522
523 if (res != (uintptr_t)AllBits) {
524 // find the position of the 0-bit
525 for (; res & 1; res_offset++) {
526 res = res >> 1;
527 }
528 assert(res_offset >= l_offset, "just checking");
529 return MIN2(res_offset, r_offset);
530 }
531 // skip over all word length 1-bit runs
532 for (index++; index < r_index; index++) {
533 res = map(index);
534 if (res != (uintptr_t)AllBits) {
535 // found a 0, return the offset
536 for (res_offset = index << LogBitsPerWord; res & 1;
537 res_offset++) {
538 res = res >> 1;
539 }
540 assert(!(res & 1), "tautology; see loop condition");
541 assert(res_offset >= l_offset, "just checking");
542 return MIN2(res_offset, r_offset);
543 }
544 }
545 return r_offset;
546 }
547 576
548 #ifndef PRODUCT 577 #ifndef PRODUCT
549 578
550 void BitMap::print_on(outputStream* st) const { 579 void BitMap::print_on(outputStream* st) const {
551 tty->print("Bitmap(%d):", size()); 580 tty->print("Bitmap(%d):", size());
556 } 585 }
557 586
558 #endif 587 #endif
559 588
560 589
561 BitMap2D::BitMap2D(uintptr_t* map, idx_t size_in_slots, idx_t bits_per_slot) 590 BitMap2D::BitMap2D(bm_word_t* map, idx_t size_in_slots, idx_t bits_per_slot)
562 : _bits_per_slot(bits_per_slot) 591 : _bits_per_slot(bits_per_slot)
563 , _map(map, size_in_slots * bits_per_slot) 592 , _map(map, size_in_slots * bits_per_slot)
564 { 593 {
565 } 594 }
566 595