RFR: 8327093: Add slice function to BitMap API

Axel Boldt-Christmas aboldtch at openjdk.org
Tue Mar 5 09:14:48 UTC 2024


On Fri, 1 Mar 2024 23:14:18 GMT, Matias Saavedra Silva <matsaave at openjdk.org> wrote:

> The BitMap does not currently have a "slice" method which can return a subset of the bitmap defined by a start and end bit. This utility can be used to analyze portions of a bitmap or to overwrite the existing map with a shorter, modified map. 
> 
> This implementation has two core methods: 
> `copy_of_range` allocates and returns a new word array as used internally by BitMap
> `truncate` overwrites the internal array with the one generated by `copy_of_range` so none of the internal workings are exposed to callers outside of BitMap.
> 
> This change is verified with an included test.

The parameter here `bool clear = true` does nothing and it is unclear to me why it is added. 

That `truncate(n)` is `[n:]` and not `[:n]` does not feel intuitive to me. Maybe having a `truncate_start` as well as `truncate_end` which covers both the explicit cases.

The `copy_of_range` logic seems broken. It is caught in the 32-bit gtests. Maybe it should be extended to cover more edge cases. Maybe add some different striped bitmaps.

src/hotspot/share/utilities/bitMap.cpp line 111:

> 109:   idx_t start_word = to_words_align_down(start_bit);
> 110:   idx_t end_word = to_words_align_up(end_bit);
> 111:   bm_word_t* const old_map = map();

I would rather all variables be const than just this one.

src/hotspot/share/utilities/bitMap.cpp line 123:

> 121: 
> 122:   // Iterate the map backwards as the shift will result in carry-out bits
> 123:   for (idx_t i = end_word; i --> start_word;) {

I guess that mutating `i` inside the conditional is to deal with `idx_t` being unsigned. But the `i --> start_word` rather than  `i-- > start_word` looks strange to me.

src/hotspot/share/utilities/bitMap.cpp line 126:

> 124:     // First iteration is a special case:
> 125:     // There may be left over bits in the last word that we want to keep while discarding the rest
> 126:     if (i == end_word - 1 && cutoff > 0) {

Is it important that the msb are cleared (beyond the `size()` bit). Could always just do `new_map[i-start_word] = old_map[i] >> shift;`

src/hotspot/share/utilities/bitMap.cpp line 135:

> 133: 
> 134:     // A full shift by BitsPerWord could be sign extended
> 135:     carry = old_map[i] << (BitsPerWord - shift) % BitsPerWord;

This contains both UB (shift too large) and it is unclear to me what this does. Should this whole loop not simply be:
```C++
  for (idx_t i = end_word; i-- > start_word;) {
    new_map[i-start_word] = old_map[i] >> shift;

    if (shift != 0) {
      new_map[i-start_word] |= carry;
      carry = old_map[i] << (BitsPerWord - shift);
    }
  }

-------------

PR Review: https://git.openjdk.org/jdk/pull/18092#pullrequestreview-1916252315
PR Review Comment: https://git.openjdk.org/jdk/pull/18092#discussion_r1512362746
PR Review Comment: https://git.openjdk.org/jdk/pull/18092#discussion_r1512362335
PR Review Comment: https://git.openjdk.org/jdk/pull/18092#discussion_r1512368106
PR Review Comment: https://git.openjdk.org/jdk/pull/18092#discussion_r1512375862


More information about the hotspot-dev mailing list