Commit 5d179546 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[zone containers] Fix iteration of const ZoneChunkList

With the current attempt, trying to iterate a const ZoneChunkList doesn't even
compile. See the bug for more info.

R=marja@chromium.org

Bug: v8:6473
Change-Id: I8de7e887398be7ba5da14dc540dd40b30df2c3fe
Reviewed-on: https://chromium-review.googlesource.com/868332Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50675}
parent 57a25168
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
template <typename T> template <typename T, bool modifiable>
class ZoneChunkListIterator; class ZoneChunkListIterator;
template <typename T> template <typename T, bool modifiable = true>
class ForwardZoneChunkListIterator; class ForwardZoneChunkListIterator;
template <typename T> template <typename T, bool modifiable = true>
class ReverseZoneChunkListIterator; class ReverseZoneChunkListIterator;
// A zone-backed hybrid of a vector and a linked list. Use it if you need a // A zone-backed hybrid of a vector and a linked list. Use it if you need a
...@@ -79,7 +79,7 @@ class ZoneChunkList : public ZoneObject { ...@@ -79,7 +79,7 @@ class ZoneChunkList : public ZoneObject {
// Quickly scans the list to retrieve the element at the given index. Will // Quickly scans the list to retrieve the element at the given index. Will
// *not* check bounds. // *not* check bounds.
ForwardZoneChunkListIterator<T> Find(const size_t index); ForwardZoneChunkListIterator<T> Find(const size_t index);
ForwardZoneChunkListIterator<const T> Find(const size_t index) const; ForwardZoneChunkListIterator<T, false> Find(const size_t index) const;
// TODO(heimbuef): Add 'rFind', seeking from the end and returning a // TODO(heimbuef): Add 'rFind', seeking from the end and returning a
// reverse iterator. // reverse iterator.
...@@ -89,16 +89,19 @@ class ZoneChunkList : public ZoneObject { ...@@ -89,16 +89,19 @@ class ZoneChunkList : public ZoneObject {
ForwardZoneChunkListIterator<T> end(); ForwardZoneChunkListIterator<T> end();
ReverseZoneChunkListIterator<T> rbegin(); ReverseZoneChunkListIterator<T> rbegin();
ReverseZoneChunkListIterator<T> rend(); ReverseZoneChunkListIterator<T> rend();
ForwardZoneChunkListIterator<const T> begin() const; ForwardZoneChunkListIterator<T, false> begin() const;
ForwardZoneChunkListIterator<const T> end() const; ForwardZoneChunkListIterator<T, false> end() const;
ReverseZoneChunkListIterator<const T> rbegin() const; ReverseZoneChunkListIterator<T, false> rbegin() const;
ReverseZoneChunkListIterator<const T> rend() const; ReverseZoneChunkListIterator<T, false> rend() const;
private: private:
friend class ZoneChunkListIterator<T>; friend class ZoneChunkListIterator<T, true>;
friend class ZoneChunkListIterator<T, false>;
friend class ForwardZoneChunkListIterator<T>; friend class ForwardZoneChunkListIterator<T>;
friend class ForwardZoneChunkListIterator<T, false>;
friend class ReverseZoneChunkListIterator<T>; friend class ReverseZoneChunkListIterator<T>;
static const uint32_t kMaxChunkCapacity = 256u; friend class ReverseZoneChunkListIterator<T, false>;
static constexpr uint32_t kMaxChunkCapacity = 256u;
STATIC_ASSERT(kMaxChunkCapacity == static_cast<uint32_t>(StartMode::kBig)); STATIC_ASSERT(kMaxChunkCapacity == static_cast<uint32_t>(StartMode::kBig));
...@@ -108,6 +111,7 @@ class ZoneChunkList : public ZoneObject { ...@@ -108,6 +111,7 @@ class ZoneChunkList : public ZoneObject {
Chunk* next_ = nullptr; Chunk* next_ = nullptr;
Chunk* previous_ = nullptr; Chunk* previous_ = nullptr;
T* items() { return reinterpret_cast<T*>(this + 1); } T* items() { return reinterpret_cast<T*>(this + 1); }
const T* items() const { return reinterpret_cast<const T*>(this + 1); }
}; };
Chunk* NewChunk(const uint32_t capacity) { Chunk* NewChunk(const uint32_t capacity) {
...@@ -135,20 +139,26 @@ class ZoneChunkList : public ZoneObject { ...@@ -135,20 +139,26 @@ class ZoneChunkList : public ZoneObject {
DISALLOW_COPY_AND_ASSIGN(ZoneChunkList); DISALLOW_COPY_AND_ASSIGN(ZoneChunkList);
}; };
template <typename T> template <typename T, bool modifiable>
class ZoneChunkListIterator { class ZoneChunkListIterator {
public: public:
T& operator*() { return current_->items()[position_]; } template <typename S>
bool operator==(const ZoneChunkListIterator& other) { using maybe_const =
typename std::conditional<modifiable, S,
typename std::add_const<S>::type>::type;
using Chunk = maybe_const<typename ZoneChunkList<T>::Chunk>;
using ChunkList = maybe_const<ZoneChunkList<T>>;
maybe_const<T>& operator*() { return current_->items()[position_]; }
bool operator==(const ZoneChunkListIterator& other) const {
return other.current_ == current_ && other.position_ == position_; return other.current_ == current_ && other.position_ == position_;
} }
bool operator!=(const ZoneChunkListIterator& other) { bool operator!=(const ZoneChunkListIterator& other) const {
return !operator==(other); return !operator==(other);
} }
protected: protected:
ZoneChunkListIterator(typename ZoneChunkList<T>::Chunk* current, ZoneChunkListIterator(Chunk* current, size_t position)
size_t position)
: current_(current), position_(position) {} : current_(current), position_(position) {}
void MoveNext() { void MoveNext() {
...@@ -168,21 +178,22 @@ class ZoneChunkListIterator { ...@@ -168,21 +178,22 @@ class ZoneChunkListIterator {
} }
} }
typename ZoneChunkList<T>::Chunk* current_; Chunk* current_;
size_t position_; size_t position_;
}; };
template <typename T> template <typename T, bool modifiable>
class ForwardZoneChunkListIterator : public ZoneChunkListIterator<T> { class ForwardZoneChunkListIterator
using ZoneChunkListIterator<T>::current_; : public ZoneChunkListIterator<T, modifiable> {
using ZoneChunkListIterator<T>::position_; using super = ZoneChunkListIterator<T, modifiable>;
using ZoneChunkListIterator<T>::MoveNext; using super::MoveNext;
using ZoneChunkListIterator<T>::MoveRNext; using super::MoveRNext;
using typename super::Chunk;
using typename super::ChunkList;
public: public:
ForwardZoneChunkListIterator(typename ZoneChunkList<T>::Chunk* current, ForwardZoneChunkListIterator(Chunk* current, size_t position)
size_t position) : ZoneChunkListIterator<T, modifiable>(current, position) {}
: ZoneChunkListIterator<T>(current, position) {}
ForwardZoneChunkListIterator& operator++() { ForwardZoneChunkListIterator& operator++() {
MoveNext(); MoveNext();
...@@ -190,7 +201,7 @@ class ForwardZoneChunkListIterator : public ZoneChunkListIterator<T> { ...@@ -190,7 +201,7 @@ class ForwardZoneChunkListIterator : public ZoneChunkListIterator<T> {
} }
ForwardZoneChunkListIterator operator++(int) { ForwardZoneChunkListIterator operator++(int) {
ForwardZoneChunkListIterator<T> clone(*this); ForwardZoneChunkListIterator clone(*this);
MoveNext(); MoveNext();
return clone; return clone;
} }
...@@ -201,39 +212,41 @@ class ForwardZoneChunkListIterator : public ZoneChunkListIterator<T> { ...@@ -201,39 +212,41 @@ class ForwardZoneChunkListIterator : public ZoneChunkListIterator<T> {
} }
ForwardZoneChunkListIterator operator--(int) { ForwardZoneChunkListIterator operator--(int) {
ForwardZoneChunkListIterator<T> clone(*this); ForwardZoneChunkListIterator clone(*this);
MoveRNext(); MoveRNext();
return clone; return clone;
} }
private: private:
friend class ZoneChunkList<T>; friend class ZoneChunkList<T>;
static ForwardZoneChunkListIterator<T> Begin(ZoneChunkList<T>* list) {
return ForwardZoneChunkListIterator<T>(list->front_, 0); static ForwardZoneChunkListIterator Begin(ChunkList* list) {
return ForwardZoneChunkListIterator(list->front_, 0);
} }
static ForwardZoneChunkListIterator<T> End(ZoneChunkList<T>* list) { static ForwardZoneChunkListIterator End(ChunkList* list) {
if (list->back_ == nullptr) return Begin(list); if (list->back_ == nullptr) return Begin(list);
DCHECK_LE(list->back_->position_, list->back_->capacity_); DCHECK_LE(list->back_->position_, list->back_->capacity_);
if (list->back_->position_ == list->back_->capacity_) { if (list->back_->position_ == list->back_->capacity_) {
return ForwardZoneChunkListIterator<T>(nullptr, 0); return ForwardZoneChunkListIterator(nullptr, 0);
} }
return ForwardZoneChunkListIterator<T>(list->back_, list->back_->position_); return ForwardZoneChunkListIterator(list->back_, list->back_->position_);
} }
}; };
template <typename T> template <typename T, bool modifiable>
class ReverseZoneChunkListIterator : public ZoneChunkListIterator<T> { class ReverseZoneChunkListIterator
using ZoneChunkListIterator<T>::current_; : public ZoneChunkListIterator<T, modifiable> {
using ZoneChunkListIterator<T>::position_; using super = ZoneChunkListIterator<T, modifiable>;
using ZoneChunkListIterator<T>::MoveNext; using super::MoveNext;
using ZoneChunkListIterator<T>::MoveRNext; using super::MoveRNext;
using typename super::Chunk;
using typename super::ChunkList;
public: public:
ReverseZoneChunkListIterator(typename ZoneChunkList<T>::Chunk* current, ReverseZoneChunkListIterator(Chunk* current, size_t position)
size_t position) : ZoneChunkListIterator<T, modifiable>(current, position) {}
: ZoneChunkListIterator<T>(current, position) {}
ReverseZoneChunkListIterator& operator++() { ReverseZoneChunkListIterator& operator++() {
MoveRNext(); MoveRNext();
...@@ -241,7 +254,7 @@ class ReverseZoneChunkListIterator : public ZoneChunkListIterator<T> { ...@@ -241,7 +254,7 @@ class ReverseZoneChunkListIterator : public ZoneChunkListIterator<T> {
} }
ReverseZoneChunkListIterator operator++(int) { ReverseZoneChunkListIterator operator++(int) {
ReverseZoneChunkListIterator<T> clone(*this); ReverseZoneChunkListIterator clone(*this);
MoveRNext(); MoveRNext();
return clone; return clone;
} }
...@@ -252,28 +265,29 @@ class ReverseZoneChunkListIterator : public ZoneChunkListIterator<T> { ...@@ -252,28 +265,29 @@ class ReverseZoneChunkListIterator : public ZoneChunkListIterator<T> {
} }
ReverseZoneChunkListIterator operator--(int) { ReverseZoneChunkListIterator operator--(int) {
ForwardZoneChunkListIterator<T> clone(*this); ReverseZoneChunkListIterator clone(*this);
MoveNext(); MoveNext();
return clone; return clone;
} }
private: private:
friend class ZoneChunkList<T>; friend class ZoneChunkList<T>;
static ReverseZoneChunkListIterator<T> Begin(ZoneChunkList<T>* list) {
static ReverseZoneChunkListIterator Begin(ChunkList* list) {
if (list->back_ == nullptr) return End(list); if (list->back_ == nullptr) return End(list);
if (list->back_->position_ == 0) { if (list->back_->position_ == 0) {
if (list->back_->previous_ != nullptr) { if (list->back_->previous_ != nullptr) {
return ReverseZoneChunkListIterator<T>( return ReverseZoneChunkListIterator(
list->back_->previous_, list->back_->previous_->capacity_ - 1); list->back_->previous_, list->back_->previous_->capacity_ - 1);
} else { } else {
return End(list); return End(list);
} }
} }
return ReverseZoneChunkListIterator<T>(list->back_, return ReverseZoneChunkListIterator(list->back_,
list->back_->position_ - 1); list->back_->position_ - 1);
} }
static ReverseZoneChunkListIterator<T> End(ZoneChunkList<T>* list) { static ReverseZoneChunkListIterator End(ChunkList* list) {
return ReverseZoneChunkListIterator<T>(nullptr, 0); return ReverseZoneChunkListIterator(nullptr, 0);
} }
}; };
...@@ -387,10 +401,10 @@ ForwardZoneChunkListIterator<T> ZoneChunkList<T>::Find(const size_t index) { ...@@ -387,10 +401,10 @@ ForwardZoneChunkListIterator<T> ZoneChunkList<T>::Find(const size_t index) {
} }
template <typename T> template <typename T>
ForwardZoneChunkListIterator<const T> ZoneChunkList<T>::Find( ForwardZoneChunkListIterator<T, false> ZoneChunkList<T>::Find(
const size_t index) const { const size_t index) const {
SeekResult seek_result = SeekIndex(index); SeekResult seek_result = SeekIndex(index);
return ForwardZoneChunkListIterator<const T>(seek_result.chunk_, return ForwardZoneChunkListIterator<T, false>(seek_result.chunk_,
seek_result.chunk_index_); seek_result.chunk_index_);
} }
...@@ -428,23 +442,23 @@ ReverseZoneChunkListIterator<T> ZoneChunkList<T>::rend() { ...@@ -428,23 +442,23 @@ ReverseZoneChunkListIterator<T> ZoneChunkList<T>::rend() {
} }
template <typename T> template <typename T>
ForwardZoneChunkListIterator<const T> ZoneChunkList<T>::begin() const { ForwardZoneChunkListIterator<T, false> ZoneChunkList<T>::begin() const {
return ForwardZoneChunkListIterator<const T>::Begin(this); return ForwardZoneChunkListIterator<T, false>::Begin(this);
} }
template <typename T> template <typename T>
ForwardZoneChunkListIterator<const T> ZoneChunkList<T>::end() const { ForwardZoneChunkListIterator<T, false> ZoneChunkList<T>::end() const {
return ForwardZoneChunkListIterator<const T>::End(this); return ForwardZoneChunkListIterator<T, false>::End(this);
} }
template <typename T> template <typename T>
ReverseZoneChunkListIterator<const T> ZoneChunkList<T>::rbegin() const { ReverseZoneChunkListIterator<T, false> ZoneChunkList<T>::rbegin() const {
return ReverseZoneChunkListIterator<const T>::Begin(this); return ReverseZoneChunkListIterator<T, false>::Begin(this);
} }
template <typename T> template <typename T>
ReverseZoneChunkListIterator<const T> ZoneChunkList<T>::rend() const { ReverseZoneChunkListIterator<T, false> ZoneChunkList<T>::rend() const {
return ReverseZoneChunkListIterator<const T>::End(this); return ReverseZoneChunkListIterator<T, false>::End(this);
} }
} // namespace internal } // namespace internal
......
...@@ -202,5 +202,30 @@ TEST(ZoneChunkList, BigCopyToTest) { ...@@ -202,5 +202,30 @@ TEST(ZoneChunkList, BigCopyToTest) {
} }
} }
void TestForwardIterationOfConstList(
const ZoneChunkList<uintptr_t>& zone_chunk_list) {
size_t count = 0;
for (uintptr_t item : zone_chunk_list) {
EXPECT_EQ(static_cast<size_t>(item), count);
count++;
}
EXPECT_EQ(count, kItemCount);
}
TEST(ZoneChunkList, ConstForwardIterationTest) {
AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
ZoneChunkList<uintptr_t> zone_chunk_list(&zone);
for (size_t i = 0; i < kItemCount; ++i) {
zone_chunk_list.push_back(static_cast<uintptr_t>(i));
}
TestForwardIterationOfConstList(zone_chunk_list);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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