From 7e1243a6f5fff4705a57cf112ada59c7ae97b7ea Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 21 Jun 2013 14:12:02 +0200 Subject: Fix build with traditional (non-thumb2) ARM 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 --- .../assembler/AssemblerBufferWithConstantPool.h | 8 +- src/3rdparty/masm/wtf/SegmentedVector.h | 276 +++++++++++++++++++++ 2 files changed, 280 insertions(+), 4 deletions(-) create mode 100644 src/3rdparty/masm/wtf/SegmentedVector.h (limited to 'src') diff --git a/src/3rdparty/masm/assembler/AssemblerBufferWithConstantPool.h b/src/3rdparty/masm/assembler/AssemblerBufferWithConstantPool.h index 5377ef0c7a..4c729a871c 100644 --- a/src/3rdparty/masm/assembler/AssemblerBufferWithConstantPool.h +++ b/src/3rdparty/masm/assembler/AssemblerBufferWithConstantPool.h @@ -105,14 +105,14 @@ public: , m_maxDistance(maxPoolSize) , m_lastConstDelta(0) { - m_pool = static_cast(fastMalloc(maxPoolSize)); - m_mask = static_cast(fastMalloc(maxPoolSize / sizeof(uint32_t))); + m_pool = static_cast(malloc(maxPoolSize)); + m_mask = static_cast(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 index 0000000000..f281c312f8 --- /dev/null +++ b/src/3rdparty/masm/wtf/SegmentedVector.h @@ -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 +#include + +namespace WTF { + + // An iterator for SegmentedVector. It supports only the pre ++ operator + template class SegmentedVector; + template class SegmentedVectorIterator { + private: + friend class SegmentedVector; + public: + typedef SegmentedVectorIterator 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& other) + { + m_vector = other.m_vector; + m_segment = other.m_segment; + m_index = other.m_index; + return *this; + } + + private: + SegmentedVectorIterator(SegmentedVector& vector, size_t segment, size_t index) + : m_vector(vector) + , m_segment(segment) + , m_index(index) + { + } + + SegmentedVector& 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 if you don't expect a lot of entries. + template + class SegmentedVector { + friend class SegmentedVectorIterator; + WTF_MAKE_NONCOPYABLE(SegmentedVector); + + public: + typedef SegmentedVectorIterator 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*>(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 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()); + 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 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(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 m_segments; + }; + +} // namespace WTF + +using WTF::SegmentedVector; + +#endif // SegmentedVector_h -- cgit v1.2.3