RFR: 8213415: BitMap::word_index_round_up overflow problems
Kim Barrett
kim.barrett at oracle.com
Tue Jun 11 01:14:22 UTC 2019
> On Jun 10, 2019, at 5:34 AM, Stefan Karlsson <stefan.karlsson at oracle.com> wrote:
Thanks for looking at this.
> http://cr.openjdk.java.net/~kbarrett/8213415/open.00/src/hotspot/share/utilities/bitMap.cpp.udiff.html
>
> template <class Allocator>
> 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) {
> + verify_max_size_limited(new_size_in_bits);
> size_t old_size_in_words = calc_size_in_words(old_size_in_bits);
> size_t new_size_in_words = calc_size_in_words(new_size_in_bits);
>
> calc_size_in_words also calls verify_max_size_limited, so maybe skip adding it here?
Good point. Done.
> ----------
>
> +void BitMap::verify_max_size_limited(idx_t bit) {
> + assert(bit <= max_size_in_bits(), "out of bounds: " SIZE_FORMAT, bit);
> +}
>
> Is the intention to verify that a 'size' is less than or equal to the 'max possible size'? If that's the case, then I think it would be better to use the name size_in_bits. Just like we do for our constructors, allocators, and initializers.
>
> Or is this actually meant to check that bit indices are within the max range? If that's the case, then why are we using <= instead of < ?
>
> (More about this below)
[Clipped the “more below”]
Your comments made me rethink some things, some of which I'd not been
entirely happy with anyway.
verify_max_size_limited is now called verify_valid_size, and is only
used for sizes, not for range boundaries.
word_index_round_up has been entirely eliminated. Instead, there is
a new internal API used by the range operations: range_begin_align_up,
range_end_align_down, with is_small_range_of_words replaced by
is_small_aligned_range. This required some fairly mechanical updates
to the implementations of the large range operations. Fortunately,
there are already gtests in this area, from JDK-8211926.
I think this tidies things up quite a bit, and hope it addresses your issues.
Looking at this also reminded me of some discussion from JDK-8211926
that apparently nobody got around to filing REFs for, so I've done that.
JDK-8225546 Cleanup BitMap index types
JDK-8225547 Improve BitMap large range handling
> void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
> assert(beg_index <= end_index, "BitMap range error");
> // Note that [0,0) and [size,size) are both valid ranges.
> - if (end_index != _size) verify_index(end_index);
> + assert(end_index <= _size, "BitMap range out of bounds");
> }
>
> This allowance to have beg_index outside of the bit range seems dubious to me. It's not something you changed, but I preferred that the old code was explicit that there was an odd special case involved.
I made this change because I found the old code confusing; I had to
think about it to decide it really would assert iff the range was
invalid. Also, the old error is confusing since the end of a range is
not an index. (Further checking is required for use as an index.) The
change makes the implementation directly correspond to the definition
of a valid range, e.g. 0 <= begin <= end <= size. (With the negative
case impossible because of an unsigned type.)
new webrevs:
full: http://cr.openjdk.java.net/~kbarrett/8213415/open.01/
incr: http://cr.openjdk.java.net/~kbarrett/8213415/open.01.inc/
More information about the hotspot-dev
mailing list