31 class BitMapClosure; |
31 class BitMapClosure; |
32 |
32 |
33 // Operations for bitmaps represented as arrays of unsigned integers. |
33 // Operations for bitmaps represented as arrays of unsigned integers. |
34 // Bit offsets are numbered from 0 to size-1. |
34 // Bit offsets are numbered from 0 to size-1. |
35 |
35 |
|
36 // The "abstract" base BitMap class. |
|
37 // |
|
38 // The constructor and destructor are protected to prevent |
|
39 // creation of BitMap instances outside of the BitMap class. |
|
40 // |
|
41 // The BitMap class doesn't use virtual calls on purpose, |
|
42 // this ensures that we don't get a vtable unnecessarily. |
|
43 // |
|
44 // The allocation of the backing storage for the BitMap are handled by |
|
45 // the subclasses. BitMap doesn't allocate or delete backing storage. |
36 class BitMap VALUE_OBJ_CLASS_SPEC { |
46 class BitMap VALUE_OBJ_CLASS_SPEC { |
37 friend class BitMap2D; |
47 friend class BitMap2D; |
38 |
48 |
39 public: |
49 public: |
40 typedef size_t idx_t; // Type used for bit and word indices. |
50 typedef size_t idx_t; // Type used for bit and word indices. |
95 void set_range_of_words (idx_t beg, idx_t end); |
101 void set_range_of_words (idx_t beg, idx_t end); |
96 void clear_range_of_words (idx_t beg, idx_t end); |
102 void clear_range_of_words (idx_t beg, idx_t end); |
97 void set_large_range_of_words (idx_t beg, idx_t end); |
103 void set_large_range_of_words (idx_t beg, idx_t end); |
98 void clear_large_range_of_words (idx_t beg, idx_t end); |
104 void clear_large_range_of_words (idx_t beg, idx_t end); |
99 |
105 |
|
106 static void clear_range_of_words(bm_word_t* map, idx_t beg, idx_t end); |
|
107 |
100 // The index of the first full word in a range. |
108 // The index of the first full word in a range. |
101 idx_t word_index_round_up(idx_t bit) const; |
109 idx_t word_index_round_up(idx_t bit) const; |
102 |
110 |
103 // Verification. |
111 // Verification. |
104 void verify_index(idx_t index) const NOT_DEBUG_RETURN; |
112 void verify_index(idx_t index) const NOT_DEBUG_RETURN; |
108 static idx_t* _pop_count_table; |
116 static idx_t* _pop_count_table; |
109 static void init_pop_count_table(); |
117 static void init_pop_count_table(); |
110 static idx_t num_set_bits(bm_word_t w); |
118 static idx_t num_set_bits(bm_word_t w); |
111 static idx_t num_set_bits_from_table(unsigned char c); |
119 static idx_t num_set_bits_from_table(unsigned char c); |
112 |
120 |
113 public: |
121 // Allocation Helpers. |
114 |
122 |
115 // Constructs a bitmap with no map, and size 0. |
123 // Allocates and clears the bitmap memory. |
116 BitMap() : _map(NULL), _size(0) {} |
124 template <class Allocator> |
117 |
125 static bm_word_t* allocate(const Allocator&, idx_t size_in_bits); |
118 // Constructs a bitmap with the given map and size. |
126 |
119 BitMap(bm_word_t* map, idx_t size_in_bits) :_map(map), _size(size_in_bits) {} |
127 // Reallocates and clears the new bitmap memory. |
120 |
128 template <class Allocator> |
121 // Constructs an empty bitmap of the given size (that is, this clears the |
129 static bm_word_t* reallocate(const Allocator&, bm_word_t* map, idx_t old_size_in_bits, idx_t new_size_in_bits); |
122 // new bitmap). Allocates the map array in resource area if |
130 |
123 // "in_resource_area" is true, else in the C heap. |
131 // Free the bitmap memory. |
124 BitMap(idx_t size_in_bits, bool in_resource_area = true); |
132 template <class Allocator> |
|
133 static void free(const Allocator&, bm_word_t* map, idx_t size_in_bits); |
|
134 |
|
135 // Protected functions, that are used by BitMap sub-classes that support them. |
|
136 |
|
137 // Resize the backing bitmap memory. |
|
138 // |
|
139 // Old bits are transfered to the new memory |
|
140 // and the extended memory is cleared. |
|
141 template <class Allocator> |
|
142 void resize(const Allocator& allocator, idx_t new_size_in_bits); |
|
143 |
|
144 // Set up and clear the bitmap memory. |
|
145 // |
|
146 // Precondition: The bitmap was default constructed and has |
|
147 // not yet had memory allocated via resize or (re)initialize. |
|
148 template <class Allocator> |
|
149 void initialize(const Allocator& allocator, idx_t size_in_bits); |
|
150 |
|
151 // Set up and clear the bitmap memory. |
|
152 // |
|
153 // Can be called on previously initialized bitmaps. |
|
154 template <class Allocator> |
|
155 void reinitialize(const Allocator& allocator, idx_t new_size_in_bits); |
125 |
156 |
126 // Set the map and size. |
157 // Set the map and size. |
127 void set_map(bm_word_t* map) { _map = map; } |
158 void update(bm_word_t* map, idx_t size) { |
128 void set_size(idx_t size_in_bits) { _size = size_in_bits; } |
159 _map = map; |
129 |
160 _size = size; |
130 // Allocates necessary data structure, either in the resource area |
161 } |
131 // or in the C heap, as indicated by "in_resource_area." |
162 |
132 // Preserves state currently in bit map by copying data. |
163 // Protected constructor and destructor. |
133 // Zeros any newly-addressable bits. |
164 BitMap(bm_word_t* map, idx_t size_in_bits) : _map(map), _size(size_in_bits) {} |
134 // If "in_resource_area" is false, frees the current map. |
165 ~BitMap() {} |
135 // (Note that this assumes that all calls to "resize" on the same BitMap |
166 |
136 // use the same value for "in_resource_area".) |
167 public: |
137 void resize(idx_t size_in_bits, bool in_resource_area = true); |
|
138 |
|
139 // Pretouch the entire range of memory this BitMap covers. |
168 // Pretouch the entire range of memory this BitMap covers. |
140 void pretouch(); |
169 void pretouch(); |
141 |
170 |
142 // Accessing |
171 // Accessing |
143 idx_t size() const { return _size; } |
|
144 idx_t size_in_bytes() const { return size_in_words() * BytesPerWord; } |
|
145 idx_t size_in_words() const { |
|
146 return calc_size_in_words(size()); |
|
147 } |
|
148 |
|
149 static idx_t calc_size_in_words(size_t size_in_bits) { |
172 static idx_t calc_size_in_words(size_t size_in_bits) { |
150 return word_index(size_in_bits + BitsPerWord - 1); |
173 return word_index(size_in_bits + BitsPerWord - 1); |
151 } |
174 } |
|
175 |
|
176 static idx_t calc_size_in_bytes(size_t size_in_bits) { |
|
177 return calc_size_in_words(size_in_bits) * BytesPerWord; |
|
178 } |
|
179 |
|
180 idx_t size() const { return _size; } |
|
181 idx_t size_in_words() const { return calc_size_in_words(size()); } |
|
182 idx_t size_in_bytes() const { return calc_size_in_bytes(size()); } |
152 |
183 |
153 bool at(idx_t index) const { |
184 bool at(idx_t index) const { |
154 verify_index(index); |
185 verify_index(index); |
155 return (*word_addr(index) & bit_mask(index)) != 0; |
186 return (*word_addr(index) & bit_mask(index)) != 0; |
156 } |
187 } |
277 // Printing |
308 // Printing |
278 void print_on(outputStream* st) const; |
309 void print_on(outputStream* st) const; |
279 #endif |
310 #endif |
280 }; |
311 }; |
281 |
312 |
|
313 // A concrete implementation of the the "abstract" BitMap class. |
|
314 // |
|
315 // The BitMapView is used when the backing storage is managed externally. |
|
316 class BitMapView : public BitMap { |
|
317 public: |
|
318 BitMapView() : BitMap(NULL, 0) {} |
|
319 BitMapView(bm_word_t* map, idx_t size_in_bits) : BitMap(map, size_in_bits) {} |
|
320 }; |
|
321 |
|
322 // A BitMap with storage in a ResourceArea. |
|
323 class ResourceBitMap : public BitMap { |
|
324 friend class TestBitMap; |
|
325 |
|
326 public: |
|
327 ResourceBitMap() : BitMap(NULL, 0) {} |
|
328 // Clears the bitmap memory. |
|
329 ResourceBitMap(idx_t size_in_bits); |
|
330 |
|
331 // Resize the backing bitmap memory. |
|
332 // |
|
333 // Old bits are transfered to the new memory |
|
334 // and the extended memory is cleared. |
|
335 void resize(idx_t new_size_in_bits); |
|
336 |
|
337 // Set up and clear the bitmap memory. |
|
338 // |
|
339 // Precondition: The bitmap was default constructed and has |
|
340 // not yet had memory allocated via resize or initialize. |
|
341 void initialize(idx_t size_in_bits); |
|
342 |
|
343 // Set up and clear the bitmap memory. |
|
344 // |
|
345 // Can be called on previously initialized bitmaps. |
|
346 void reinitialize(idx_t size_in_bits); |
|
347 }; |
|
348 |
|
349 // A BitMap with storage in a specific Arena. |
|
350 class ArenaBitMap : public BitMap { |
|
351 public: |
|
352 // Clears the bitmap memory. |
|
353 ArenaBitMap(Arena* arena, idx_t size_in_bits); |
|
354 |
|
355 private: |
|
356 // Don't allow copy or assignment. |
|
357 ArenaBitMap(const ArenaBitMap&); |
|
358 ArenaBitMap& operator=(const ArenaBitMap&); |
|
359 }; |
|
360 |
|
361 // A BitMap with storage in the CHeap. |
|
362 class CHeapBitMap : public BitMap { |
|
363 friend class TestBitMap; |
|
364 |
|
365 private: |
|
366 // Don't allow copy or assignment, to prevent the |
|
367 // allocated memory from leaking out to other instances. |
|
368 CHeapBitMap(const CHeapBitMap&); |
|
369 CHeapBitMap& operator=(const CHeapBitMap&); |
|
370 |
|
371 public: |
|
372 CHeapBitMap() : BitMap(NULL, 0) {} |
|
373 // Clears the bitmap memory. |
|
374 CHeapBitMap(idx_t size_in_bits); |
|
375 ~CHeapBitMap(); |
|
376 |
|
377 // Resize the backing bitmap memory. |
|
378 // |
|
379 // Old bits are transfered to the new memory |
|
380 // and the extended memory is cleared. |
|
381 void resize(idx_t new_size_in_bits); |
|
382 |
|
383 // Set up and clear the bitmap memory. |
|
384 // |
|
385 // Precondition: The bitmap was default constructed and has |
|
386 // not yet had memory allocated via resize or initialize. |
|
387 void initialize(idx_t size_in_bits); |
|
388 |
|
389 // Set up and clear the bitmap memory. |
|
390 // |
|
391 // Can be called on previously initialized bitmaps. |
|
392 void reinitialize(idx_t size_in_bits); |
|
393 }; |
|
394 |
282 // Convenience class wrapping BitMap which provides multiple bits per slot. |
395 // Convenience class wrapping BitMap which provides multiple bits per slot. |
283 class BitMap2D VALUE_OBJ_CLASS_SPEC { |
396 class BitMap2D VALUE_OBJ_CLASS_SPEC { |
284 public: |
397 public: |
285 typedef BitMap::idx_t idx_t; // Type used for bit and word indices. |
398 typedef BitMap::idx_t idx_t; // Type used for bit and word indices. |
286 typedef BitMap::bm_word_t bm_word_t; // Element type of array that |
399 typedef BitMap::bm_word_t bm_word_t; // Element type of array that |
287 // represents the bitmap. |
400 // represents the bitmap. |
288 private: |
401 private: |
289 BitMap _map; |
402 ResourceBitMap _map; |
290 idx_t _bits_per_slot; |
403 idx_t _bits_per_slot; |
291 |
404 |
292 idx_t bit_index(idx_t slot_index, idx_t bit_within_slot_index) const { |
405 idx_t bit_index(idx_t slot_index, idx_t bit_within_slot_index) const { |
293 return slot_index * _bits_per_slot + bit_within_slot_index; |
406 return slot_index * _bits_per_slot + bit_within_slot_index; |
294 } |
407 } |
295 |
408 |
297 assert(index < _bits_per_slot, "bit_within_slot index out of bounds"); |
410 assert(index < _bits_per_slot, "bit_within_slot index out of bounds"); |
298 } |
411 } |
299 |
412 |
300 public: |
413 public: |
301 // Construction. bits_per_slot must be greater than 0. |
414 // Construction. bits_per_slot must be greater than 0. |
302 BitMap2D(bm_word_t* map, idx_t size_in_slots, idx_t bits_per_slot); |
415 BitMap2D(idx_t bits_per_slot) : |
|
416 _map(), _bits_per_slot(bits_per_slot) {} |
303 |
417 |
304 // Allocates necessary data structure in resource area. bits_per_slot must be greater than 0. |
418 // Allocates necessary data structure in resource area. bits_per_slot must be greater than 0. |
305 BitMap2D(idx_t size_in_slots, idx_t bits_per_slot); |
419 BitMap2D(idx_t size_in_slots, idx_t bits_per_slot) : |
|
420 _map(size_in_slots * bits_per_slot), _bits_per_slot(bits_per_slot) {} |
306 |
421 |
307 idx_t size_in_bits() { |
422 idx_t size_in_bits() { |
308 return _map.size(); |
423 return _map.size(); |
309 } |
424 } |
310 |
425 |