1 /*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "memory/resourceArea.hpp"
28 #include "runtime/atomic.hpp"
29 #include "utilities/bitMap.inline.hpp"
30 #include "utilities/copy.hpp"
31 #include "utilities/debug.hpp"
32 #include "utilities/population_count.hpp"
33
34 STATIC_ASSERT(sizeof(BitMap::bm_word_t) == BytesPerWord); // "Implementation assumption."
35
36 typedef BitMap::bm_word_t bm_word_t;
37 typedef BitMap::idx_t idx_t;
38
39 class ResourceBitMapAllocator : StackObj {
40 public:
allocate(idx_t size_in_words) const41 bm_word_t* allocate(idx_t size_in_words) const {
42 return NEW_RESOURCE_ARRAY(bm_word_t, size_in_words);
43 }
free(bm_word_t * map,idx_t size_in_words) const44 void free(bm_word_t* map, idx_t size_in_words) const {
45 // Don't free resource allocated arrays.
46 }
47 };
48
49 class CHeapBitMapAllocator : StackObj {
50 MEMFLAGS _flags;
51
52 public:
CHeapBitMapAllocator(MEMFLAGS flags)53 CHeapBitMapAllocator(MEMFLAGS flags) : _flags(flags) {}
allocate(size_t size_in_words) const54 bm_word_t* allocate(size_t size_in_words) const {
55 return ArrayAllocator<bm_word_t>::allocate(size_in_words, _flags);
56 }
free(bm_word_t * map,idx_t size_in_words) const57 void free(bm_word_t* map, idx_t size_in_words) const {
58 ArrayAllocator<bm_word_t>::free(map, size_in_words);
59 }
60 };
61
62 class ArenaBitMapAllocator : StackObj {
63 Arena* _arena;
64
65 public:
ArenaBitMapAllocator(Arena * arena)66 ArenaBitMapAllocator(Arena* arena) : _arena(arena) {}
allocate(idx_t size_in_words) const67 bm_word_t* allocate(idx_t size_in_words) const {
68 return (bm_word_t*)_arena->Amalloc(size_in_words * BytesPerWord);
69 }
free(bm_word_t * map,idx_t size_in_words) const70 void free(bm_word_t* map, idx_t size_in_words) const {
71 // ArenaBitMaps currently don't free memory.
72 }
73 };
74
75 template <class Allocator>
reallocate(const Allocator & allocator,bm_word_t * old_map,idx_t old_size_in_bits,idx_t new_size_in_bits,bool clear)76 BitMap::bm_word_t* BitMap::reallocate(const Allocator& allocator, bm_word_t* old_map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear) {
77 size_t old_size_in_words = calc_size_in_words(old_size_in_bits);
78 size_t new_size_in_words = calc_size_in_words(new_size_in_bits);
79
80 bm_word_t* map = NULL;
81
82 if (new_size_in_words > 0) {
83 map = allocator.allocate(new_size_in_words);
84
85 if (old_map != NULL) {
86 Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) map,
87 MIN2(old_size_in_words, new_size_in_words));
88 }
89
90 if (clear && new_size_in_words > old_size_in_words) {
91 clear_range_of_words(map, old_size_in_words, new_size_in_words);
92 }
93 }
94
95 if (old_map != NULL) {
96 allocator.free(old_map, old_size_in_words);
97 }
98
99 return map;
100 }
101
102 template <class Allocator>
allocate(const Allocator & allocator,idx_t size_in_bits,bool clear)103 bm_word_t* BitMap::allocate(const Allocator& allocator, idx_t size_in_bits, bool clear) {
104 // Reuse reallocate to ensure that the new memory is cleared.
105 return reallocate(allocator, NULL, 0, size_in_bits, clear);
106 }
107
108 template <class Allocator>
free(const Allocator & allocator,bm_word_t * map,idx_t size_in_bits)109 void BitMap::free(const Allocator& allocator, bm_word_t* map, idx_t size_in_bits) {
110 bm_word_t* ret = reallocate(allocator, map, size_in_bits, 0);
111 assert(ret == NULL, "Reallocate shouldn't have allocated");
112 }
113
114 template <class Allocator>
resize(const Allocator & allocator,idx_t new_size_in_bits,bool clear)115 void BitMap::resize(const Allocator& allocator, idx_t new_size_in_bits, bool clear) {
116 bm_word_t* new_map = reallocate(allocator, map(), size(), new_size_in_bits, clear);
117
118 update(new_map, new_size_in_bits);
119 }
120
121 template <class Allocator>
initialize(const Allocator & allocator,idx_t size_in_bits,bool clear)122 void BitMap::initialize(const Allocator& allocator, idx_t size_in_bits, bool clear) {
123 assert(map() == NULL, "precondition");
124 assert(size() == 0, "precondition");
125
126 resize(allocator, size_in_bits, clear);
127 }
128
129 template <class Allocator>
reinitialize(const Allocator & allocator,idx_t new_size_in_bits,bool clear)130 void BitMap::reinitialize(const Allocator& allocator, idx_t new_size_in_bits, bool clear) {
131 // Remove previous bits - no need to clear
132 resize(allocator, 0, false /* clear */);
133
134 initialize(allocator, new_size_in_bits, clear);
135 }
136
ResourceBitMap(idx_t size_in_bits,bool clear)137 ResourceBitMap::ResourceBitMap(idx_t size_in_bits, bool clear)
138 : BitMap(allocate(ResourceBitMapAllocator(), size_in_bits, clear), size_in_bits) {
139 }
140
resize(idx_t new_size_in_bits)141 void ResourceBitMap::resize(idx_t new_size_in_bits) {
142 BitMap::resize(ResourceBitMapAllocator(), new_size_in_bits, true /* clear */);
143 }
144
initialize(idx_t size_in_bits)145 void ResourceBitMap::initialize(idx_t size_in_bits) {
146 BitMap::initialize(ResourceBitMapAllocator(), size_in_bits, true /* clear */);
147 }
148
reinitialize(idx_t size_in_bits)149 void ResourceBitMap::reinitialize(idx_t size_in_bits) {
150 BitMap::reinitialize(ResourceBitMapAllocator(), size_in_bits, true /* clear */);
151 }
152
ArenaBitMap(Arena * arena,idx_t size_in_bits)153 ArenaBitMap::ArenaBitMap(Arena* arena, idx_t size_in_bits)
154 : BitMap(allocate(ArenaBitMapAllocator(arena), size_in_bits), size_in_bits) {
155 }
156
CHeapBitMap(idx_t size_in_bits,MEMFLAGS flags,bool clear)157 CHeapBitMap::CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags, bool clear)
158 : BitMap(allocate(CHeapBitMapAllocator(flags), size_in_bits, clear), size_in_bits), _flags(flags) {
159 }
160
~CHeapBitMap()161 CHeapBitMap::~CHeapBitMap() {
162 free(CHeapBitMapAllocator(_flags), map(), size());
163 }
164
resize(idx_t new_size_in_bits,bool clear)165 void CHeapBitMap::resize(idx_t new_size_in_bits, bool clear) {
166 BitMap::resize(CHeapBitMapAllocator(_flags), new_size_in_bits, clear);
167 }
168
initialize(idx_t size_in_bits,bool clear)169 void CHeapBitMap::initialize(idx_t size_in_bits, bool clear) {
170 BitMap::initialize(CHeapBitMapAllocator(_flags), size_in_bits, clear);
171 }
172
reinitialize(idx_t size_in_bits,bool clear)173 void CHeapBitMap::reinitialize(idx_t size_in_bits, bool clear) {
174 BitMap::reinitialize(CHeapBitMapAllocator(_flags), size_in_bits, clear);
175 }
176
177 #ifdef ASSERT
verify_size(idx_t size_in_bits)178 void BitMap::verify_size(idx_t size_in_bits) {
179 assert(size_in_bits <= max_size_in_bits(),
180 "out of bounds: " SIZE_FORMAT, size_in_bits);
181 }
182
verify_index(idx_t bit) const183 void BitMap::verify_index(idx_t bit) const {
184 assert(bit < _size,
185 "BitMap index out of bounds: " SIZE_FORMAT " >= " SIZE_FORMAT,
186 bit, _size);
187 }
188
verify_limit(idx_t bit) const189 void BitMap::verify_limit(idx_t bit) const {
190 assert(bit <= _size,
191 "BitMap limit out of bounds: " SIZE_FORMAT " > " SIZE_FORMAT,
192 bit, _size);
193 }
194
verify_range(idx_t beg,idx_t end) const195 void BitMap::verify_range(idx_t beg, idx_t end) const {
196 assert(beg <= end,
197 "BitMap range error: " SIZE_FORMAT " > " SIZE_FORMAT, beg, end);
198 verify_limit(end);
199 }
200 #endif // #ifdef ASSERT
201
pretouch()202 void BitMap::pretouch() {
203 os::pretouch_memory(word_addr(0), word_addr(size()));
204 }
205
set_range_within_word(idx_t beg,idx_t end)206 void BitMap::set_range_within_word(idx_t beg, idx_t end) {
207 // With a valid range (beg <= end), this test ensures that end != 0, as
208 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
209 if (beg != end) {
210 bm_word_t mask = inverted_bit_mask_for_range(beg, end);
211 *word_addr(beg) |= ~mask;
212 }
213 }
214
clear_range_within_word(idx_t beg,idx_t end)215 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
216 // With a valid range (beg <= end), this test ensures that end != 0, as
217 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
218 if (beg != end) {
219 bm_word_t mask = inverted_bit_mask_for_range(beg, end);
220 *word_addr(beg) &= mask;
221 }
222 }
223
par_put_range_within_word(idx_t beg,idx_t end,bool value)224 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
225 assert(value == 0 || value == 1, "0 for clear, 1 for set");
226 // With a valid range (beg <= end), this test ensures that end != 0, as
227 // required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
228 if (beg != end) {
229 bm_word_t* pw = word_addr(beg);
230 bm_word_t w = *pw;
231 bm_word_t mr = inverted_bit_mask_for_range(beg, end);
232 bm_word_t nw = value ? (w | ~mr) : (w & mr);
233 while (true) {
234 bm_word_t res = Atomic::cmpxchg(pw, w, nw);
235 if (res == w) break;
236 w = res;
237 nw = value ? (w | ~mr) : (w & mr);
238 }
239 }
240 }
241
set_range(idx_t beg,idx_t end)242 void BitMap::set_range(idx_t beg, idx_t end) {
243 verify_range(beg, end);
244
245 idx_t beg_full_word = to_words_align_up(beg);
246 idx_t end_full_word = to_words_align_down(end);
247
248 if (beg_full_word < end_full_word) {
249 // The range includes at least one full word.
250 set_range_within_word(beg, bit_index(beg_full_word));
251 set_range_of_words(beg_full_word, end_full_word);
252 set_range_within_word(bit_index(end_full_word), end);
253 } else {
254 // The range spans at most 2 partial words.
255 idx_t boundary = MIN2(bit_index(beg_full_word), end);
256 set_range_within_word(beg, boundary);
257 set_range_within_word(boundary, end);
258 }
259 }
260
clear_range(idx_t beg,idx_t end)261 void BitMap::clear_range(idx_t beg, idx_t end) {
262 verify_range(beg, end);
263
264 idx_t beg_full_word = to_words_align_up(beg);
265 idx_t end_full_word = to_words_align_down(end);
266
267 if (beg_full_word < end_full_word) {
268 // The range includes at least one full word.
269 clear_range_within_word(beg, bit_index(beg_full_word));
270 clear_range_of_words(beg_full_word, end_full_word);
271 clear_range_within_word(bit_index(end_full_word), end);
272 } else {
273 // The range spans at most 2 partial words.
274 idx_t boundary = MIN2(bit_index(beg_full_word), end);
275 clear_range_within_word(beg, boundary);
276 clear_range_within_word(boundary, end);
277 }
278 }
279
is_small_range_of_words(idx_t beg_full_word,idx_t end_full_word)280 bool BitMap::is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word) {
281 // There is little point to call large version on small ranges.
282 // Need to check carefully, keeping potential idx_t over/underflow in mind,
283 // because beg_full_word > end_full_word can occur when beg and end are in
284 // the same word.
285 // The threshold should be at least one word.
286 STATIC_ASSERT(small_range_words >= 1);
287 return beg_full_word + small_range_words >= end_full_word;
288 }
289
set_large_range(idx_t beg,idx_t end)290 void BitMap::set_large_range(idx_t beg, idx_t end) {
291 verify_range(beg, end);
292
293 idx_t beg_full_word = to_words_align_up(beg);
294 idx_t end_full_word = to_words_align_down(end);
295
296 if (is_small_range_of_words(beg_full_word, end_full_word)) {
297 set_range(beg, end);
298 return;
299 }
300
301 // The range includes at least one full word.
302 set_range_within_word(beg, bit_index(beg_full_word));
303 set_large_range_of_words(beg_full_word, end_full_word);
304 set_range_within_word(bit_index(end_full_word), end);
305 }
306
clear_large_range(idx_t beg,idx_t end)307 void BitMap::clear_large_range(idx_t beg, idx_t end) {
308 verify_range(beg, end);
309
310 idx_t beg_full_word = to_words_align_up(beg);
311 idx_t end_full_word = to_words_align_down(end);
312
313 if (is_small_range_of_words(beg_full_word, end_full_word)) {
314 clear_range(beg, end);
315 return;
316 }
317
318 // The range includes at least one full word.
319 clear_range_within_word(beg, bit_index(beg_full_word));
320 clear_large_range_of_words(beg_full_word, end_full_word);
321 clear_range_within_word(bit_index(end_full_word), end);
322 }
323
at_put(idx_t offset,bool value)324 void BitMap::at_put(idx_t offset, bool value) {
325 if (value) {
326 set_bit(offset);
327 } else {
328 clear_bit(offset);
329 }
330 }
331
332 // Return true to indicate that this thread changed
333 // the bit, false to indicate that someone else did.
334 // In either case, the requested bit is in the
335 // requested state some time during the period that
336 // this thread is executing this call. More importantly,
337 // if no other thread is executing an action to
338 // change the requested bit to a state other than
339 // the one that this thread is trying to set it to,
340 // then the the bit is in the expected state
341 // at exit from this method. However, rather than
342 // make such a strong assertion here, based on
343 // assuming such constrained use (which though true
344 // today, could change in the future to service some
345 // funky parallel algorithm), we encourage callers
346 // to do such verification, as and when appropriate.
par_at_put(idx_t bit,bool value)347 bool BitMap::par_at_put(idx_t bit, bool value) {
348 return value ? par_set_bit(bit) : par_clear_bit(bit);
349 }
350
at_put_range(idx_t start_offset,idx_t end_offset,bool value)351 void BitMap::at_put_range(idx_t start_offset, idx_t end_offset, bool value) {
352 if (value) {
353 set_range(start_offset, end_offset);
354 } else {
355 clear_range(start_offset, end_offset);
356 }
357 }
358
par_at_put_range(idx_t beg,idx_t end,bool value)359 void BitMap::par_at_put_range(idx_t beg, idx_t end, bool value) {
360 verify_range(beg, end);
361
362 idx_t beg_full_word = to_words_align_up(beg);
363 idx_t end_full_word = to_words_align_down(end);
364
365 if (beg_full_word < end_full_word) {
366 // The range includes at least one full word.
367 par_put_range_within_word(beg, bit_index(beg_full_word), value);
368 if (value) {
369 set_range_of_words(beg_full_word, end_full_word);
370 } else {
371 clear_range_of_words(beg_full_word, end_full_word);
372 }
373 par_put_range_within_word(bit_index(end_full_word), end, value);
374 } else {
375 // The range spans at most 2 partial words.
376 idx_t boundary = MIN2(bit_index(beg_full_word), end);
377 par_put_range_within_word(beg, boundary, value);
378 par_put_range_within_word(boundary, end, value);
379 }
380
381 }
382
at_put_large_range(idx_t beg,idx_t end,bool value)383 void BitMap::at_put_large_range(idx_t beg, idx_t end, bool value) {
384 if (value) {
385 set_large_range(beg, end);
386 } else {
387 clear_large_range(beg, end);
388 }
389 }
390
par_at_put_large_range(idx_t beg,idx_t end,bool value)391 void BitMap::par_at_put_large_range(idx_t beg, idx_t end, bool value) {
392 verify_range(beg, end);
393
394 idx_t beg_full_word = to_words_align_up(beg);
395 idx_t end_full_word = to_words_align_down(end);
396
397 if (is_small_range_of_words(beg_full_word, end_full_word)) {
398 par_at_put_range(beg, end, value);
399 return;
400 }
401
402 // The range includes at least one full word.
403 par_put_range_within_word(beg, bit_index(beg_full_word), value);
404 if (value) {
405 set_large_range_of_words(beg_full_word, end_full_word);
406 } else {
407 clear_large_range_of_words(beg_full_word, end_full_word);
408 }
409 par_put_range_within_word(bit_index(end_full_word), end, value);
410 }
411
tail_mask(idx_t tail_bits)412 inline bm_word_t tail_mask(idx_t tail_bits) {
413 assert(tail_bits != 0, "precondition"); // Works, but shouldn't be called.
414 assert(tail_bits < (idx_t)BitsPerWord, "precondition");
415 return (bm_word_t(1) << tail_bits) - 1;
416 }
417
418 // Get the low tail_bits of value, which is the last partial word of a map.
tail_of_map(bm_word_t value,idx_t tail_bits)419 inline bm_word_t tail_of_map(bm_word_t value, idx_t tail_bits) {
420 return value & tail_mask(tail_bits);
421 }
422
423 // Compute the new last word of a map with a non-aligned length.
424 // new_value has the new trailing bits of the map in the low tail_bits.
425 // old_value is the last word of the map, including bits beyond the end.
426 // Returns old_value with the low tail_bits replaced by the corresponding
427 // bits in new_value.
merge_tail_of_map(bm_word_t new_value,bm_word_t old_value,idx_t tail_bits)428 inline bm_word_t merge_tail_of_map(bm_word_t new_value,
429 bm_word_t old_value,
430 idx_t tail_bits) {
431 bm_word_t mask = tail_mask(tail_bits);
432 return (new_value & mask) | (old_value & ~mask);
433 }
434
contains(const BitMap & other) const435 bool BitMap::contains(const BitMap& other) const {
436 assert(size() == other.size(), "must have same size");
437 const bm_word_t* dest_map = map();
438 const bm_word_t* other_map = other.map();
439 idx_t limit = to_words_align_down(size());
440 for (idx_t index = 0; index < limit; ++index) {
441 // false if other bitmap has bits set which are clear in this bitmap.
442 if ((~dest_map[index] & other_map[index]) != 0) return false;
443 }
444 idx_t rest = bit_in_word(size());
445 // true unless there is a partial-word tail in which the other
446 // bitmap has bits set which are clear in this bitmap.
447 return (rest == 0) || tail_of_map(~dest_map[limit] & other_map[limit], rest) == 0;
448 }
449
intersects(const BitMap & other) const450 bool BitMap::intersects(const BitMap& other) const {
451 assert(size() == other.size(), "must have same size");
452 const bm_word_t* dest_map = map();
453 const bm_word_t* other_map = other.map();
454 idx_t limit = to_words_align_down(size());
455 for (idx_t index = 0; index < limit; ++index) {
456 if ((dest_map[index] & other_map[index]) != 0) return true;
457 }
458 idx_t rest = bit_in_word(size());
459 // false unless there is a partial-word tail with non-empty intersection.
460 return (rest > 0) && tail_of_map(dest_map[limit] & other_map[limit], rest) != 0;
461 }
462
set_union(const BitMap & other)463 void BitMap::set_union(const BitMap& other) {
464 assert(size() == other.size(), "must have same size");
465 bm_word_t* dest_map = map();
466 const bm_word_t* other_map = other.map();
467 idx_t limit = to_words_align_down(size());
468 for (idx_t index = 0; index < limit; ++index) {
469 dest_map[index] |= other_map[index];
470 }
471 idx_t rest = bit_in_word(size());
472 if (rest > 0) {
473 bm_word_t orig = dest_map[limit];
474 dest_map[limit] = merge_tail_of_map(orig | other_map[limit], orig, rest);
475 }
476 }
477
set_difference(const BitMap & other)478 void BitMap::set_difference(const BitMap& other) {
479 assert(size() == other.size(), "must have same size");
480 bm_word_t* dest_map = map();
481 const bm_word_t* other_map = other.map();
482 idx_t limit = to_words_align_down(size());
483 for (idx_t index = 0; index < limit; ++index) {
484 dest_map[index] &= ~other_map[index];
485 }
486 idx_t rest = bit_in_word(size());
487 if (rest > 0) {
488 bm_word_t orig = dest_map[limit];
489 dest_map[limit] = merge_tail_of_map(orig & ~other_map[limit], orig, rest);
490 }
491 }
492
set_intersection(const BitMap & other)493 void BitMap::set_intersection(const BitMap& other) {
494 assert(size() == other.size(), "must have same size");
495 bm_word_t* dest_map = map();
496 const bm_word_t* other_map = other.map();
497 idx_t limit = to_words_align_down(size());
498 for (idx_t index = 0; index < limit; ++index) {
499 dest_map[index] &= other_map[index];
500 }
501 idx_t rest = bit_in_word(size());
502 if (rest > 0) {
503 bm_word_t orig = dest_map[limit];
504 dest_map[limit] = merge_tail_of_map(orig & other_map[limit], orig, rest);
505 }
506 }
507
set_union_with_result(const BitMap & other)508 bool BitMap::set_union_with_result(const BitMap& other) {
509 assert(size() == other.size(), "must have same size");
510 bool changed = false;
511 bm_word_t* dest_map = map();
512 const bm_word_t* other_map = other.map();
513 idx_t limit = to_words_align_down(size());
514 for (idx_t index = 0; index < limit; ++index) {
515 bm_word_t orig = dest_map[index];
516 bm_word_t temp = orig | other_map[index];
517 changed = changed || (temp != orig);
518 dest_map[index] = temp;
519 }
520 idx_t rest = bit_in_word(size());
521 if (rest > 0) {
522 bm_word_t orig = dest_map[limit];
523 bm_word_t temp = merge_tail_of_map(orig | other_map[limit], orig, rest);
524 changed = changed || (temp != orig);
525 dest_map[limit] = temp;
526 }
527 return changed;
528 }
529
set_difference_with_result(const BitMap & other)530 bool BitMap::set_difference_with_result(const BitMap& other) {
531 assert(size() == other.size(), "must have same size");
532 bool changed = false;
533 bm_word_t* dest_map = map();
534 const bm_word_t* other_map = other.map();
535 idx_t limit = to_words_align_down(size());
536 for (idx_t index = 0; index < limit; ++index) {
537 bm_word_t orig = dest_map[index];
538 bm_word_t temp = orig & ~other_map[index];
539 changed = changed || (temp != orig);
540 dest_map[index] = temp;
541 }
542 idx_t rest = bit_in_word(size());
543 if (rest > 0) {
544 bm_word_t orig = dest_map[limit];
545 bm_word_t temp = merge_tail_of_map(orig & ~other_map[limit], orig, rest);
546 changed = changed || (temp != orig);
547 dest_map[limit] = temp;
548 }
549 return changed;
550 }
551
set_intersection_with_result(const BitMap & other)552 bool BitMap::set_intersection_with_result(const BitMap& other) {
553 assert(size() == other.size(), "must have same size");
554 bool changed = false;
555 bm_word_t* dest_map = map();
556 const bm_word_t* other_map = other.map();
557 idx_t limit = to_words_align_down(size());
558 for (idx_t index = 0; index < limit; ++index) {
559 bm_word_t orig = dest_map[index];
560 bm_word_t temp = orig & other_map[index];
561 changed = changed || (temp != orig);
562 dest_map[index] = temp;
563 }
564 idx_t rest = bit_in_word(size());
565 if (rest > 0) {
566 bm_word_t orig = dest_map[limit];
567 bm_word_t temp = merge_tail_of_map(orig & other_map[limit], orig, rest);
568 changed = changed || (temp != orig);
569 dest_map[limit] = temp;
570 }
571 return changed;
572 }
573
set_from(const BitMap & other)574 void BitMap::set_from(const BitMap& other) {
575 assert(size() == other.size(), "must have same size");
576 bm_word_t* dest_map = map();
577 const bm_word_t* other_map = other.map();
578 idx_t copy_words = to_words_align_down(size());
579 Copy::disjoint_words((HeapWord*)other_map, (HeapWord*)dest_map, copy_words);
580 idx_t rest = bit_in_word(size());
581 if (rest > 0) {
582 dest_map[copy_words] = merge_tail_of_map(other_map[copy_words],
583 dest_map[copy_words],
584 rest);
585 }
586 }
587
is_same(const BitMap & other) const588 bool BitMap::is_same(const BitMap& other) const {
589 assert(size() == other.size(), "must have same size");
590 const bm_word_t* dest_map = map();
591 const bm_word_t* other_map = other.map();
592 idx_t limit = to_words_align_down(size());
593 for (idx_t index = 0; index < limit; ++index) {
594 if (dest_map[index] != other_map[index]) return false;
595 }
596 idx_t rest = bit_in_word(size());
597 return (rest == 0) || (tail_of_map(dest_map[limit] ^ other_map[limit], rest) == 0);
598 }
599
is_full() const600 bool BitMap::is_full() const {
601 const bm_word_t* words = map();
602 idx_t limit = to_words_align_down(size());
603 for (idx_t index = 0; index < limit; ++index) {
604 if (~words[index] != 0) return false;
605 }
606 idx_t rest = bit_in_word(size());
607 return (rest == 0) || (tail_of_map(~words[limit], rest) == 0);
608 }
609
is_empty() const610 bool BitMap::is_empty() const {
611 const bm_word_t* words = map();
612 idx_t limit = to_words_align_down(size());
613 for (idx_t index = 0; index < limit; ++index) {
614 if (words[index] != 0) return false;
615 }
616 idx_t rest = bit_in_word(size());
617 return (rest == 0) || (tail_of_map(words[limit], rest) == 0);
618 }
619
clear_large()620 void BitMap::clear_large() {
621 clear_large_range_of_words(0, size_in_words());
622 }
623
624 // Note that if the closure itself modifies the bitmap
625 // then modifications in and to the left of the _bit_ being
626 // currently sampled will not be seen. Note also that the
627 // interval [leftOffset, rightOffset) is right open.
iterate(BitMapClosure * blk,idx_t leftOffset,idx_t rightOffset)628 bool BitMap::iterate(BitMapClosure* blk, idx_t leftOffset, idx_t rightOffset) {
629 verify_range(leftOffset, rightOffset);
630
631 idx_t startIndex = to_words_align_down(leftOffset);
632 idx_t endIndex = to_words_align_up(rightOffset);
633 for (idx_t index = startIndex, offset = leftOffset;
634 offset < rightOffset && index < endIndex;
635 offset = (++index) << LogBitsPerWord) {
636 idx_t rest = map(index) >> (offset & (BitsPerWord - 1));
637 for (; offset < rightOffset && rest != 0; offset++) {
638 if (rest & 1) {
639 if (!blk->do_bit(offset)) return false;
640 // resample at each closure application
641 // (see, for instance, CMS bug 4525989)
642 rest = map(index) >> (offset & (BitsPerWord -1));
643 }
644 rest = rest >> 1;
645 }
646 }
647 return true;
648 }
649
count_one_bits() const650 BitMap::idx_t BitMap::count_one_bits() const {
651 idx_t sum = 0;
652 for (idx_t i = 0; i < size_in_words(); i++) {
653 bm_word_t w = map()[i];
654 sum += population_count(w);
655 }
656 return sum;
657 }
658
print_on_error(outputStream * st,const char * prefix) const659 void BitMap::print_on_error(outputStream* st, const char* prefix) const {
660 st->print_cr("%s[" PTR_FORMAT ", " PTR_FORMAT ")",
661 prefix, p2i(map()), p2i((char*)map() + (size() >> LogBitsPerByte)));
662 }
663
write_to(bm_word_t * buffer,size_t buffer_size_in_bytes) const664 void BitMap::write_to(bm_word_t* buffer, size_t buffer_size_in_bytes) const {
665 assert(buffer_size_in_bytes == size_in_bytes(), "must be");
666 memcpy(buffer, _map, size_in_bytes());
667 }
668
669 #ifndef PRODUCT
670
print_on(outputStream * st) const671 void BitMap::print_on(outputStream* st) const {
672 tty->print("Bitmap(" SIZE_FORMAT "):", size());
673 for (idx_t index = 0; index < size(); index++) {
674 tty->print("%c", at(index) ? '1' : '0');
675 }
676 tty->cr();
677 }
678
679 #endif
680