Title: [275901] trunk
Revision
275901
Author
[email protected]
Date
2021-04-13 12:54:06 -0700 (Tue, 13 Apr 2021)

Log Message

[WTF] Add Vector&& move constructor / assignment to FixedVector and RefCountedArray
https://bugs.webkit.org/show_bug.cgi?id=224475

Reviewed by Ryosuke Niwa.

Source/WTF:

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):

Tools:

* TestWebKitAPI/Tests/WTF/FixedVector.cpp:
(TestWebKitAPI::TEST):

Modified Paths

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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to