Commit 8cd5d85d authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[utils] Fix new length computation when growing BitVector

The {std::min} followed by a loop does ensure that the new length is
bigger than {needed_value}, but does not ensure that we always allocate
at least {kInitialLength}. Maybe this was intended to be {std::max}?

Anyway, this CL replaces the loop by a computation which ensures that we
allocate a power of two that is greater than {needed_value} and at least
{kInitialLength}.
It also adds a CHECK to guard against integer overflows.

R=jkummerow@chromium.org

Bug: v8:13063
Change-Id: I374d304204a499536643a6c5df7111231d41d4bd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3760674Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81724}
parent 63e054f5
......@@ -361,14 +361,19 @@ class GrowableBitVector {
private:
static constexpr int kInitialLength = 1024;
// The allocated size is always a power of two, and needs to be strictly
// bigger than the biggest contained value.
static constexpr int kMaxSupportedValue = (1 << 30) - 1;
bool InBitsRange(int value) const { return bits_.length() > value; }
V8_NOINLINE void Grow(int needed_value, Zone* zone) {
DCHECK(!InBitsRange(needed_value));
int new_length =
base::bits::RoundUpToPowerOfTwo32(static_cast<uint32_t>(needed_value));
new_length = std::min(new_length, kInitialLength);
while (new_length <= needed_value) new_length *= 2;
// Ensure that {RoundUpToPowerOfTwo32} does not overflow {int} range.
CHECK_GE(kMaxSupportedValue, needed_value);
int new_length = std::max(
kInitialLength, static_cast<int>(base::bits::RoundUpToPowerOfTwo32(
static_cast<uint32_t>(needed_value + 1))));
bits_.Resize(new_length, zone);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment