| Index: Source/wtf/Vector.h
|
| diff --git a/Source/wtf/Vector.h b/Source/wtf/Vector.h
|
| index f353c01cd4140420a5b574bca4c90a2ba1aaa8f1..88e532fd3d5f3e95248dd538628f268b59b42657 100644
|
| --- a/Source/wtf/Vector.h
|
| +++ b/Source/wtf/Vector.h
|
| @@ -79,6 +79,9 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| template<typename T>
|
| struct VectorUnusedSlotClearer<false, T> {
|
| static void clear(T*, T*) { }
|
| +#if ENABLE(ASSERT)
|
| + static void checkCleared(const T*, const T*) { }
|
| +#endif
|
| };
|
|
|
| template<typename T>
|
| @@ -89,6 +92,17 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| // do not visit them (or at least it does not matter if they do).
|
| memset(begin, 0, sizeof(T) * (end - begin));
|
| }
|
| +
|
| +#if ENABLE(ASSERT)
|
| + static void checkCleared(const T* begin, const T* end)
|
| + {
|
| + const unsigned char* unusedArea = reinterpret_cast<const unsigned char*>(begin);
|
| + const unsigned char* endAddress = reinterpret_cast<const unsigned char*>(end);
|
| + ASSERT(endAddress >= unusedArea);
|
| + for (int i = 0; i < endAddress - unusedArea; ++i)
|
| + ASSERT(!unusedArea[i]);
|
| + }
|
| +#endif
|
| };
|
|
|
| template <bool canInitializeWithMemset, typename T>
|
| @@ -331,6 +345,13 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| VectorUnusedSlotClearer<Allocator::isGarbageCollected && (VectorTraits<T>::needsDestruction || ShouldBeTraced<VectorTraits<T>>::value), T>::clear(from, to);
|
| }
|
|
|
| + void checkUnusedSlots(const T* from, const T* to)
|
| + {
|
| +#if ENABLE(ASSERT) && !defined(ANNOTATE_CONTIGUOUS_CONTAINER)
|
| + VectorUnusedSlotClearer<Allocator::isGarbageCollected && (VectorTraits<T>::needsDestruction || ShouldBeTraced<VectorTraits<T>>::value), T>::checkCleared(from, to);
|
| +#endif
|
| + }
|
| +
|
| protected:
|
| VectorBufferBase()
|
| : m_buffer(0)
|
| @@ -419,6 +440,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| using Base::capacity;
|
|
|
| using Base::clearUnusedSlots;
|
| + using Base::checkUnusedSlots;
|
|
|
| bool hasOutOfLineBuffer() const
|
| {
|
| @@ -539,11 +561,13 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| ANNOTATE_CHANGE_SIZE(other.inlineBuffer(), inlineCapacity, other.m_size, m_size);
|
| TypeOperations::swap(inlineBuffer(), inlineBuffer() + other.m_size, other.inlineBuffer());
|
| TypeOperations::move(inlineBuffer() + other.m_size, inlineBuffer() + m_size, other.inlineBuffer() + other.m_size);
|
| + Base::clearUnusedSlots(inlineBuffer() + other.m_size, inlineBuffer() + m_size);
|
| ANNOTATE_CHANGE_SIZE(inlineBuffer(), inlineCapacity, m_size, other.m_size);
|
| } else {
|
| ANNOTATE_CHANGE_SIZE(inlineBuffer(), inlineCapacity, m_size, other.m_size);
|
| TypeOperations::swap(inlineBuffer(), inlineBuffer() + m_size, other.inlineBuffer());
|
| TypeOperations::move(other.inlineBuffer() + m_size, other.inlineBuffer() + other.m_size, inlineBuffer() + m_size);
|
| + Base::clearUnusedSlots(other.inlineBuffer() + m_size, other.inlineBuffer() + other.m_size);
|
| ANNOTATE_CHANGE_SIZE(other.inlineBuffer(), inlineCapacity, other.m_size, m_size);
|
| }
|
| } else if (buffer() == inlineBuffer()) {
|
| @@ -552,6 +576,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| other.m_buffer = other.inlineBuffer();
|
| ANNOTATE_NEW_BUFFER(other.m_buffer, inlineCapacity, m_size);
|
| TypeOperations::move(inlineBuffer(), inlineBuffer() + m_size, other.inlineBuffer());
|
| + Base::clearUnusedSlots(inlineBuffer(), inlineBuffer() + m_size);
|
| std::swap(m_capacity, other.m_capacity);
|
| } else if (other.buffer() == other.inlineBuffer()) {
|
| ANNOTATE_DELETE_BUFFER(other.m_buffer, inlineCapacity, other.m_size);
|
| @@ -559,6 +584,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| m_buffer = inlineBuffer();
|
| ANNOTATE_NEW_BUFFER(m_buffer, inlineCapacity, other.m_size);
|
| TypeOperations::move(other.inlineBuffer(), other.inlineBuffer() + other.m_size, inlineBuffer());
|
| + Base::clearUnusedSlots(other.inlineBuffer(), other.inlineBuffer() + other.m_size);
|
| std::swap(m_capacity, other.m_capacity);
|
| } else {
|
| std::swap(m_buffer, other.m_buffer);
|
| @@ -779,6 +805,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| using Base::allocateBuffer;
|
| using Base::allocationSize;
|
| using Base::clearUnusedSlots;
|
| + using Base::checkUnusedSlots;
|
| };
|
|
|
| template<typename T, size_t inlineCapacity, typename Allocator>
|
| @@ -970,6 +997,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| {
|
| if (size <= m_size) {
|
| TypeOperations::destruct(begin() + size, end());
|
| + clearUnusedSlots(begin() + size, end());
|
| ANNOTATE_CHANGE_SIZE(begin(), capacity(), m_size, size);
|
| } else {
|
| if (size > capacity())
|
| @@ -1026,6 +1054,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| Base::allocateExpandedBuffer(newCapacity);
|
| ANNOTATE_NEW_BUFFER(begin(), capacity(), m_size);
|
| TypeOperations::move(oldBuffer, oldEnd, begin());
|
| + clearUnusedSlots(oldBuffer, oldEnd);
|
| ANNOTATE_DELETE_BUFFER(oldBuffer, oldCapacity, m_size);
|
| Base::deallocateBuffer(oldBuffer);
|
| }
|
| @@ -1066,6 +1095,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| if (begin() != oldBuffer) {
|
| ANNOTATE_NEW_BUFFER(begin(), capacity(), m_size);
|
| TypeOperations::move(oldBuffer, oldEnd, begin());
|
| + clearUnusedSlots(oldBuffer, oldEnd);
|
| ANNOTATE_DELETE_BUFFER(oldBuffer, oldCapacity, m_size);
|
| }
|
| } else {
|
| @@ -1287,6 +1317,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
|
| if (ShouldBeTraced<VectorTraits<T>>::value) {
|
| for (const T* bufferEntry = bufferBegin; bufferEntry != bufferEnd; bufferEntry++)
|
| Allocator::template trace<VisitorDispatcher, T, VectorTraits<T>>(visitor, *const_cast<T*>(bufferEntry));
|
| + checkUnusedSlots(buffer() + size(), buffer() + capacity());
|
| }
|
| if (this->hasOutOfLineBuffer())
|
| Allocator::markNoTracing(visitor, buffer());
|
|
|