Fix build with traditional (non-thumb2) ARM
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 21 Jun 2013 12:12:02 +0000 (14:12 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Mon, 24 Jun 2013 08:43:49 +0000 (10:43 +0200)
Pull in the BSD licensed SegmentedVector (that is based on Vector)
and use malloc/free instead of fastMalloc/fastFree in the constant pool.

Change-Id: I25aeb34a6f778f2c886a331851d8fc1dd0fc1d61
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/3rdparty/masm/assembler/AssemblerBufferWithConstantPool.h
src/3rdparty/masm/wtf/SegmentedVector.h [new file with mode: 0644]

index 5377ef0..4c729a8 100644 (file)
@@ -105,14 +105,14 @@ public:
         , m_maxDistance(maxPoolSize)
         , m_lastConstDelta(0)
     {
-        m_pool = static_cast<uint32_t*>(fastMalloc(maxPoolSize));
-        m_mask = static_cast<char*>(fastMalloc(maxPoolSize / sizeof(uint32_t)));
+        m_pool = static_cast<uint32_t*>(malloc(maxPoolSize));
+        m_mask = static_cast<char*>(malloc(maxPoolSize / sizeof(uint32_t)));
     }
 
     ~AssemblerBufferWithConstantPool()
     {
-        fastFree(m_mask);
-        fastFree(m_pool);
+        free(m_mask);
+        free(m_pool);
     }
 
     void ensureSpace(int space)
diff --git a/src/3rdparty/masm/wtf/SegmentedVector.h b/src/3rdparty/masm/wtf/SegmentedVector.h
new file mode 100644 (file)
index 0000000..f281c31
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SegmentedVector_h
+#define SegmentedVector_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WTF {
+
+    // An iterator for SegmentedVector. It supports only the pre ++ operator
+    template <typename T, size_t SegmentSize = 8, size_t InlineCapacity = 32> class SegmentedVector;
+    template <typename T, size_t SegmentSize = 8, size_t InlineCapacity = 32> class SegmentedVectorIterator {
+    private:
+        friend class SegmentedVector<T, SegmentSize, InlineCapacity>;
+    public:
+        typedef SegmentedVectorIterator<T, SegmentSize, InlineCapacity> Iterator;
+
+        ~SegmentedVectorIterator() { }
+
+        T& operator*() const { return m_vector.m_segments.at(m_segment)->at(m_index); }
+        T* operator->() const { return &m_vector.m_segments.at(m_segment)->at(m_index); }
+
+        // Only prefix ++ operator supported
+        Iterator& operator++()
+        {
+            ASSERT(m_index != SegmentSize);
+            ++m_index;
+            if (m_index >= m_vector.m_segments.at(m_segment)->size())  {
+                if (m_segment + 1 < m_vector.m_segments.size()) {
+                    ASSERT(m_vector.m_segments.at(m_segment)->size() > 0);
+                    ++m_segment;
+                    m_index = 0;
+                } else {
+                    // Points to the "end" symbol
+                    m_segment = 0;
+                    m_index = SegmentSize;
+                }
+            }
+            return *this;
+        }
+
+        bool operator==(const Iterator& other) const
+        {
+            return m_index == other.m_index && m_segment == other.m_segment && &m_vector == &other.m_vector;
+        }
+
+        bool operator!=(const Iterator& other) const
+        {
+            return m_index != other.m_index || m_segment != other.m_segment || &m_vector != &other.m_vector;
+        }
+
+        SegmentedVectorIterator& operator=(const SegmentedVectorIterator<T, SegmentSize, InlineCapacity>& other)
+        {
+            m_vector = other.m_vector;
+            m_segment = other.m_segment;
+            m_index = other.m_index;
+            return *this;
+        }
+
+    private:
+        SegmentedVectorIterator(SegmentedVector<T, SegmentSize, InlineCapacity>& vector, size_t segment, size_t index)
+            : m_vector(vector)
+            , m_segment(segment)
+            , m_index(index)
+        {
+        }
+
+        SegmentedVector<T, SegmentSize, InlineCapacity>& m_vector;
+        size_t m_segment;
+        size_t m_index;
+    };
+
+    // SegmentedVector is just like Vector, but it doesn't move the values
+    // stored in its buffer when it grows. Therefore, it is safe to keep
+    // pointers into a SegmentedVector. The default tuning values are
+    // optimized for segmented vectors that get large; you may want to use
+    // SegmentedVector<thingy, 1, 0> if you don't expect a lot of entries.
+    template <typename T, size_t SegmentSize, size_t InlineCapacity>
+    class SegmentedVector {
+        friend class SegmentedVectorIterator<T, SegmentSize, InlineCapacity>;
+        WTF_MAKE_NONCOPYABLE(SegmentedVector);
+
+    public:
+        typedef SegmentedVectorIterator<T, SegmentSize, InlineCapacity> Iterator;
+
+        SegmentedVector()
+            : m_size(0)
+        {
+            m_segments.append(&m_inlineSegment);
+        }
+
+        ~SegmentedVector()
+        {
+            deleteAllSegments();
+        }
+
+        size_t size() const { return m_size; }
+        bool isEmpty() const { return !size(); }
+
+        T& at(size_t index)
+        {
+            if (index < SegmentSize)
+                return m_inlineSegment[index];
+            return segmentFor(index)->at(subscriptFor(index));
+        }
+
+        const T& at(size_t index) const
+        {
+            return const_cast<SegmentedVector<T, SegmentSize, InlineCapacity>*>(this)->at(index);
+        }
+
+        T& operator[](size_t index)
+        {
+            return at(index);
+        }
+
+        const T& operator[](size_t index) const
+        {
+            return at(index);
+        }
+
+        T& last()
+        {
+            return at(size() - 1);
+        }
+
+        template <typename U> void append(const U& value)
+        {
+            ++m_size;
+
+            if (m_size <= SegmentSize) {
+                m_inlineSegment.append(value);
+                return;
+            }
+
+            if (!segmentExistsFor(m_size - 1))
+                m_segments.append(new Segment);
+            segmentFor(m_size - 1)->append(value);
+        }
+
+        T& alloc()
+        {
+            append<T>(T());
+            return last();
+        }
+
+        void removeLast()
+        {
+            if (m_size <= SegmentSize)
+                m_inlineSegment.removeLast();
+            else
+                segmentFor(m_size - 1)->removeLast();
+            --m_size;
+        }
+
+        void grow(size_t size)
+        {
+            ASSERT(size > m_size);
+            ensureSegmentsFor(size);
+            m_size = size;
+        }
+
+        void clear()
+        {
+            deleteAllSegments();
+            m_segments.resize(1);
+            m_inlineSegment.clear();
+            m_size = 0;
+        }
+
+        Iterator begin()
+        {
+            return Iterator(*this, 0, m_size ? 0 : SegmentSize);
+        }
+
+        Iterator end()
+        {
+            return Iterator(*this, 0, SegmentSize);
+        }
+        
+        void shrinkToFit()
+        {
+            m_segments.shrinkToFit();
+        }
+
+    private:
+        typedef Vector<T, SegmentSize> Segment;
+
+        void deleteAllSegments()
+        {
+            // Skip the first segment, because it's our inline segment, which was
+            // not created by new.
+            for (size_t i = 1; i < m_segments.size(); i++)
+                delete m_segments[i];
+        }
+
+        bool segmentExistsFor(size_t index)
+        {
+            return index / SegmentSize < m_segments.size();
+        }
+
+        Segment* segmentFor(size_t index)
+        {
+            return m_segments[index / SegmentSize];
+        }
+
+        size_t subscriptFor(size_t index)
+        {
+            return index % SegmentSize;
+        }
+
+        void ensureSegmentsFor(size_t size)
+        {
+            size_t segmentCount = m_size / SegmentSize;
+            if (m_size % SegmentSize)
+                ++segmentCount;
+            segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment.
+
+            size_t neededSegmentCount = size / SegmentSize;
+            if (size % SegmentSize)
+                ++neededSegmentCount;
+
+            // Fill up to N - 1 segments.
+            size_t end = neededSegmentCount - 1;
+            for (size_t i = segmentCount - 1; i < end; ++i)
+                ensureSegment(i, SegmentSize);
+
+            // Grow segment N to accomodate the remainder.
+            ensureSegment(end, subscriptFor(size - 1) + 1);
+        }
+
+        void ensureSegment(size_t segmentIndex, size_t size)
+        {
+            ASSERT_WITH_SECURITY_IMPLICATION(segmentIndex <= m_segments.size());
+            if (segmentIndex == m_segments.size())
+                m_segments.append(new Segment);
+            m_segments[segmentIndex]->grow(size);
+        }
+
+        size_t m_size;
+        Segment m_inlineSegment;
+        Vector<Segment*, InlineCapacity> m_segments;
+    };
+
+} // namespace WTF
+
+using WTF::SegmentedVector;
+
+#endif // SegmentedVector_h