Diff
Modified: trunk/Source/WTF/ChangeLog (275900 => 275901)
--- trunk/Source/WTF/ChangeLog 2021-04-13 19:51:25 UTC (rev 275900)
+++ trunk/Source/WTF/ChangeLog 2021-04-13 19:54:06 UTC (rev 275901)
@@ -1,3 +1,23 @@
+2021-04-13 Yusuke Suzuki <[email protected]>
+
+ [WTF] Add Vector&& move constructor / assignment to FixedVector and RefCountedArray
+ https://bugs.webkit.org/show_bug.cgi?id=224475
+
+ Reviewed by Ryosuke Niwa.
+
+ This patch adds move constructor and move-assignment taking Vector to FixedVector / RefCountedArray.
+ This allows transferring MoveOnly things from Vector to FixedVector.
+
+ * wtf/FixedVector.h:
+ (WTF::FixedVector::FixedVector):
+ (WTF::FixedVector::operator=):
+ * wtf/RefCountedArray.h:
+ (WTF::RefCountedArray::RefCountedArray):
+ (WTF::RefCountedArray::operator=):
+ (WTF::RefCountedArray::~RefCountedArray):
+ (WTF::RefCountedArray::allocateUninitializedData):
+ (WTF::RefCountedArray::assign):
+
2021-04-13 Alex Christensen <[email protected]>
Revert r275172
Modified: trunk/Source/WTF/wtf/FixedVector.h (275900 => 275901)
--- trunk/Source/WTF/wtf/FixedVector.h 2021-04-13 19:51:25 UTC (rev 275900)
+++ trunk/Source/WTF/wtf/FixedVector.h 2021-04-13 19:54:06 UTC (rev 275901)
@@ -75,6 +75,18 @@
return *this;
}
+ template<size_t inlineCapacity, typename OverflowHandler>
+ explicit FixedVector(Vector<T, inlineCapacity, OverflowHandler>&& other)
+ : m_storage(WTFMove(other))
+ { }
+
+ template<size_t inlineCapacity, typename OverflowHandler>
+ FixedVector& operator=(Vector<T, inlineCapacity, OverflowHandler>&& other)
+ {
+ m_storage = WTFMove(other);
+ return *this;
+ }
+
size_t size() const { return m_storage.size(); }
bool isEmpty() const { return m_storage.isEmpty(); }
size_t byteSize() const { return m_storage.byteSize(); }
Modified: trunk/Source/WTF/wtf/RefCountedArray.h (275900 => 275901)
--- trunk/Source/WTF/wtf/RefCountedArray.h 2021-04-13 19:51:25 UTC (rev 275900)
+++ trunk/Source/WTF/wtf/RefCountedArray.h 2021-04-13 19:54:06 UTC (rev 275901)
@@ -78,11 +78,7 @@
return;
}
- T* data = "" + sizeof(T) * size)))->payload();
- m_data = data;
- Header::fromPayload(data)->refCount = 1;
- Header::fromPayload(data)->length = size;
- ASSERT(Header::fromPayload(data)->length == size);
+ m_data = allocateUninitializedData(size);
VectorTypeOperations<T>::initializeIfNonPOD(begin(), end());
}
@@ -104,14 +100,26 @@
PtrTraits::exchange(m_data, nullptr);
return;
}
-
- T* data = "" + sizeof(T) * other.size())))->payload();
+
+ T* data = ""
m_data = data;
- Header::fromPayload(data)->refCount = 1;
- Header::fromPayload(data)->length = other.size();
- ASSERT(Header::fromPayload(data)->length == other.size());
VectorTypeOperations<T>::uninitializedCopy(other.begin(), other.end(), data);
}
+
+ template<size_t inlineCapacity, typename OverflowHandler>
+ explicit RefCountedArray(Vector<T, inlineCapacity, OverflowHandler>&& other)
+ {
+ Vector<T, inlineCapacity, OverflowHandler> vector(WTFMove(other));
+ if (vector.isEmpty()) {
+ PtrTraits::exchange(m_data, nullptr);
+ return;
+ }
+
+ T* data = ""
+ m_data = data;
+ for (unsigned index = 0; index < vector.size(); ++index)
+ new (data + index) T(WTFMove(vector[index]));
+ }
template<typename OtherTraits = PtrTraits>
RefCountedArray& operator=(const RefCountedArray<T, OtherTraits>& other)
@@ -131,17 +139,17 @@
if (other.isEmpty())
PtrTraits::exchange(m_data, nullptr);
else {
- T* data = "" + sizeof(T) * other.size())))->payload();
+ T* data = ""
m_data = data;
- Header::fromPayload(data)->refCount = 1;
- Header::fromPayload(data)->length = other.size();
- ASSERT(Header::fromPayload(data)->length == other.size());
VectorTypeOperations<T>::uninitializedCopy(other.begin(), other.end(), data);
}
if (!oldData)
return *this;
- if (--Header::fromPayload(oldData)->refCount)
+ unsigned refCount = Header::fromPayload(oldData)->refCount - 1;
+ if (refCount) {
+ Header::fromPayload(oldData)->refCount = refCount;
return *this;
+ }
VectorTypeOperations<T>::destruct(oldData, oldData + Header::fromPayload(oldData)->length);
RefCountedArrayMalloc::free(Header::fromPayload(oldData));
@@ -148,13 +156,42 @@
return *this;
}
+ template<size_t inlineCapacity, typename OverflowHandler>
+ RefCountedArray& operator=(Vector<T, inlineCapacity, OverflowHandler>&& other)
+ {
+ Vector<T, inlineCapacity, OverflowHandler> vector(WTFMove(other));
+ T* oldData = data();
+ if (vector.isEmpty())
+ PtrTraits::exchange(m_data, nullptr);
+ else {
+ T* data = ""
+ m_data = data;
+ for (unsigned index = 0; index < vector.size(); ++index)
+ new (data + index) T(WTFMove(vector[index]));
+ }
+ if (!oldData)
+ return *this;
+ unsigned refCount = Header::fromPayload(oldData)->refCount - 1;
+ if (refCount) {
+ Header::fromPayload(oldData)->refCount = refCount;
+ return *this;
+ }
+ VectorTypeOperations<T>::destruct(oldData, oldData + Header::fromPayload(oldData)->length);
+
+ RefCountedArrayMalloc::free(Header::fromPayload(oldData));
+ return *this;
+ }
+
~RefCountedArray()
{
if (!m_data)
return;
T* data = ""
- if (--Header::fromPayload(data)->refCount)
+ unsigned refCount = Header::fromPayload(data)->refCount - 1;
+ if (refCount) {
+ Header::fromPayload(data)->refCount = refCount;
return;
+ }
VectorTypeOperations<T>::destruct(begin(), end());
RefCountedArrayMalloc::free(Header::fromPayload(data));
}
@@ -248,6 +285,15 @@
bool operator==(const RefCountedArray& other) const { return this->operator==<PtrTraits>(other); }
private:
+ static T* allocateUninitializedData(unsigned length)
+ {
+ T* data = "" + sizeof(T) * length)))->payload();
+ Header::fromPayload(data)->refCount = 1;
+ Header::fromPayload(data)->length = length;
+ ASSERT(Header::fromPayload(data)->length == length);
+ return data;
+ }
+
template<typename OtherTraits = PtrTraits>
RefCountedArray& assign(const RefCountedArray<T, OtherTraits>& other)
{
@@ -259,8 +305,11 @@
if (!oldData)
return *this;
- if (--Header::fromPayload(oldData)->refCount)
+ unsigned refCount = Header::fromPayload(oldData)->refCount - 1;
+ if (refCount) {
+ Header::fromPayload(oldData)->refCount = refCount;
return *this;
+ }
VectorTypeOperations<T>::destruct(oldData, oldData + Header::fromPayload(oldData)->length);
RefCountedArrayMalloc::free(Header::fromPayload(oldData));
Modified: trunk/Tools/ChangeLog (275900 => 275901)
--- trunk/Tools/ChangeLog 2021-04-13 19:51:25 UTC (rev 275900)
+++ trunk/Tools/ChangeLog 2021-04-13 19:54:06 UTC (rev 275901)
@@ -1,3 +1,13 @@
+2021-04-13 Yusuke Suzuki <[email protected]>
+
+ [WTF] Add Vector&& move constructor / assignment to FixedVector and RefCountedArray
+ https://bugs.webkit.org/show_bug.cgi?id=224475
+
+ Reviewed by Ryosuke Niwa.
+
+ * TestWebKitAPI/Tests/WTF/FixedVector.cpp:
+ (TestWebKitAPI::TEST):
+
2021-04-13 Alex Christensen <[email protected]>
Remove SharedBuffer's equality operators with Ref<SharedBuffer>
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/FixedVector.cpp (275900 => 275901)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/FixedVector.cpp 2021-04-13 19:51:25 UTC (rev 275900)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/FixedVector.cpp 2021-04-13 19:54:06 UTC (rev 275901)
@@ -146,6 +146,31 @@
EXPECT_EQ(vec2[i], i);
}
+TEST(WTF_FixedVector, MoveVector)
+{
+ auto vec1 = Vector<MoveOnly>::from(MoveOnly(0), MoveOnly(1), MoveOnly(2), MoveOnly(3));
+ EXPECT_EQ(vec1.size(), 4U);
+ FixedVector<MoveOnly> vec2(WTFMove(vec1));
+ EXPECT_EQ(vec1.size(), 0U);
+ EXPECT_EQ(vec2.size(), 4U);
+ for (unsigned index = 0; index < vec2.size(); ++index)
+ EXPECT_EQ(vec2[index].value(), index);
+}
+
+TEST(WTF_FixedVector, MoveAssignVector)
+{
+ FixedVector<MoveOnly> vec2;
+ {
+ auto vec1 = Vector<MoveOnly>::from(MoveOnly(0), MoveOnly(1), MoveOnly(2), MoveOnly(3));
+ EXPECT_EQ(vec1.size(), 4U);
+ vec2 = WTFMove(vec1);
+ EXPECT_EQ(vec1.size(), 0U);
+ }
+ EXPECT_EQ(vec2.size(), 4U);
+ for (unsigned index = 0; index < vec2.size(); ++index)
+ EXPECT_EQ(vec2[index].value(), index);
+}
+
TEST(WTF_FixedVector, Swap)
{
FixedVector<unsigned> vec1(3);
@@ -262,4 +287,42 @@
EXPECT_TRUE(flags[i]);
}
+TEST(WTF_FixedVector, MoveKeepsData)
+{
+ {
+ FixedVector<unsigned> vec1(3);
+ auto* data1 = vec1.data();
+ FixedVector<unsigned> vec2(WTFMove(vec1));
+ EXPECT_EQ(vec2.data(), data1);
+ }
+ {
+ FixedVector<unsigned> vec1(3);
+ auto* data1 = vec1.data();
+ FixedVector<unsigned> vec2;
+ vec2 = WTFMove(vec1);
+ EXPECT_EQ(vec2.data(), data1);
+ }
+}
+
+TEST(WTF_FixedVector, MoveKeepsDataNested)
+{
+ {
+ Vector<FixedVector<unsigned>> vec1;
+ vec1.append(FixedVector<unsigned>(3));
+ auto* data1 = vec1[0].data();
+ FixedVector<FixedVector<unsigned>> vec2(WTFMove(vec1));
+ EXPECT_EQ(vec2.size(), 1U);
+ EXPECT_EQ(vec2[0].data(), data1);
+ }
+ {
+ Vector<FixedVector<unsigned>> vec1;
+ vec1.append(FixedVector<unsigned>(3));
+ auto* data1 = vec1[0].data();
+ FixedVector<FixedVector<unsigned>> vec2;
+ vec2 = WTFMove(vec1);
+ EXPECT_EQ(vec2.size(), 1U);
+ EXPECT_EQ(vec2[0].data(), data1);
+ }
+}
+
} // namespace TestWebKitAPI