Fix a bug in ZoneChunkList::Find() at chunk boundaries.

We would return the wrong chunk for the first element past the chunk
boundary, e.g. if the first chunk was size=8, then Find(8) would
return an address in the first block rather than the second one.

Bug: v8:8077
Change-Id: I90281f853dd7ca68dc065ed773d0ae9787f00988
Reviewed-on: https://chromium-review.googlesource.com/1183483
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55294}
This commit is contained in:
Peter Marshall 2018-08-21 17:14:34 +02:00 committed by Commit Bot
parent 21e7b70c9c
commit 2923d2d44a
2 changed files with 23 additions and 2 deletions

View File

@ -249,7 +249,9 @@ class ZoneChunkListIterator
}
ZoneChunkListIterator(Chunk* current, size_t position)
: current_(current), position_(position) {}
: current_(current), position_(position) {
DCHECK(current == nullptr || position < current->capacity_);
}
template <bool move_backward>
void Move() {
@ -323,6 +325,7 @@ void ZoneChunkList<T>::push_back(const T& item) {
back_->items()[back_->position_] = item;
++back_->position_;
++size_;
DCHECK_LE(back_->position_, back_->capacity_);
}
template <typename T>
@ -356,10 +359,11 @@ typename ZoneChunkList<T>::SeekResult ZoneChunkList<T>::SeekIndex(
size_t index) const {
DCHECK_LT(index, size());
Chunk* current = front_;
while (index > current->capacity_) {
while (index >= current->capacity_) {
index -= current->capacity_;
current = current->next_;
}
DCHECK_LT(index, current->capacity_);
return {current, static_cast<uint32_t>(index)};
}

View File

@ -335,5 +335,22 @@ TEST(ZoneChunkList, AdvanceEndTest) {
CHECK_EQ(iterator_advance, zone_chunk_list.end());
}
TEST(ZoneChunkList, FindOverChunkBoundary) {
AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
ZoneChunkList<int> zone_chunk_list(&zone);
// Make sure we get two chunks.
int chunk_size = static_cast<int>(ZoneChunkList<int>::StartMode::kSmall);
for (int i = 0; i < chunk_size + 1; ++i) {
zone_chunk_list.push_back(i);
}
for (int i = 0; i < chunk_size + 1; ++i) {
CHECK_EQ(i, *zone_chunk_list.Find(i));
}
}
} // namespace internal
} // namespace v8