Reduce dynamic memory allocation in css jit.
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jul 2014 04:49:39 +0000 (04:49 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jul 2014 04:49:39 +0000 (04:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134416

Reviewed by Benjamin Poulain.

Source/WebCore:
* cssjit/FunctionCall.h:
(WebCore::FunctionCall::saveAllocatedRegisters):
* cssjit/RegisterAllocator.h:
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::addPseudoClassType):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
* cssjit/StackAllocator.h:
(WebCore::StackAllocator::push):
(WebCore::StackAllocator::pop):
Use inlineCapacity template parameter to reduce malloc calls.
I use 32 as the inline capacity for non-register related vectors because that
is probably big enough for the selector compiler, and if it is not then a malloc
call will not be significant because the selector is very complex.

Source/WTF:
* wtf/Deque.h:
Added inlineCapacity optional template parameter.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170697 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/Deque.h
Source/WebCore/ChangeLog
Source/WebCore/cssjit/FunctionCall.h
Source/WebCore/cssjit/RegisterAllocator.h
Source/WebCore/cssjit/SelectorCompiler.cpp
Source/WebCore/cssjit/StackAllocator.h

index 15224aa..6b0df6c 100644 (file)
@@ -1,3 +1,13 @@
+2014-07-01  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce dynamic memory allocation in css jit.
+        https://bugs.webkit.org/show_bug.cgi?id=134416
+
+        Reviewed by Benjamin Poulain.
+
+        * wtf/Deque.h:
+        Added inlineCapacity optional template parameter.
+
 2014-06-30  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r170605.
index 840b9a1..a20e4a2 100644 (file)
 
 namespace WTF {
 
-    template<typename T> class DequeIteratorBase;
-    template<typename T> class DequeIterator;
-    template<typename T> class DequeConstIterator;
+    template<typename T, size_t inlineCapacity> class DequeIteratorBase;
+    template<typename T, size_t inlineCapacity> class DequeIterator;
+    template<typename T, size_t inlineCapacity> class DequeConstIterator;
 
-    template<typename T>
+    template<typename T, size_t inlineCapacity = 0>
     class Deque {
         WTF_MAKE_FAST_ALLOCATED;
     public:
-        typedef DequeIterator<T> iterator;
-        typedef DequeConstIterator<T> const_iterator;
+        typedef DequeIterator<T, inlineCapacity> iterator;
+        typedef DequeConstIterator<T, inlineCapacity> const_iterator;
         typedef std::reverse_iterator<iterator> reverse_iterator;
         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
         Deque();
-        Deque(const Deque<T>&);
-        Deque& operator=(const Deque<T>&);
+        Deque(const Deque<T, inlineCapacity>&);
+        Deque& operator=(const Deque<T, inlineCapacity>&);
         ~Deque();
 
-        void swap(Deque<T>&);
+        void swap(Deque<T, inlineCapacity>&);
 
         size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; }
         bool isEmpty() const { return m_start == m_end; }
@@ -91,11 +91,11 @@ namespace WTF {
         iterator findIf(Predicate&&);
 
     private:
-        friend class DequeIteratorBase<T>;
+        friend class DequeIteratorBase<T, inlineCapacity>;
 
-        typedef VectorBuffer<T, 0> Buffer;
+        typedef VectorBuffer<T, inlineCapacity> Buffer;
         typedef VectorTypeOperations<T> TypeOperations;
-        typedef DequeIteratorBase<T> IteratorBase;
+        typedef DequeIteratorBase<T, inlineCapacity> IteratorBase;
 
         void remove(size_t position);
         void invalidateIterators();
@@ -113,11 +113,11 @@ namespace WTF {
 #endif
     };
 
-    template<typename T>
+    template<typename T, size_t inlineCapacity>
     class DequeIteratorBase {
     protected:
         DequeIteratorBase();
-        DequeIteratorBase(const Deque<T>*, size_t);
+        DequeIteratorBase(const Deque<T, inlineCapacity>*, size_t);
         DequeIteratorBase(const DequeIteratorBase&);
         DequeIteratorBase& operator=(const DequeIteratorBase&);
         ~DequeIteratorBase();
@@ -138,10 +138,10 @@ namespace WTF {
         void checkValidity() const;
         void checkValidity(const DequeIteratorBase&) const;
 
-        Deque<T>* m_deque;
+        Deque<T, inlineCapacity>* m_deque;
         size_t m_index;
 
-        friend class Deque<T>;
+        friend class Deque<T, inlineCapacity>;
 
 #ifndef NDEBUG
         mutable DequeIteratorBase* m_next;
@@ -149,11 +149,11 @@ namespace WTF {
 #endif
     };
 
-    template<typename T>
-    class DequeIterator : public DequeIteratorBase<T> {
+    template<typename T, size_t inlineCapacity>
+    class DequeIterator : public DequeIteratorBase<T, inlineCapacity> {
     private:
-        typedef DequeIteratorBase<T> Base;
-        typedef DequeIterator<T> Iterator;
+        typedef DequeIteratorBase<T, inlineCapacity> Base;
+        typedef DequeIterator<T, inlineCapacity> Iterator;
 
     public:
         typedef ptrdiff_t difference_type;
@@ -162,7 +162,8 @@ namespace WTF {
         typedef T& reference;
         typedef std::bidirectional_iterator_tag iterator_category;
 
-        DequeIterator(Deque<T>* deque, size_t index) : Base(deque, index) { }
+        DequeIterator(Deque<T, inlineCapacity>* deque, size_t index)
+            : Base(deque, index) { }
 
         DequeIterator(const Iterator& other) : Base(other) { }
         DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
@@ -179,12 +180,12 @@ namespace WTF {
         // postfix -- intentionally omitted
     };
 
-    template<typename T>
-    class DequeConstIterator : public DequeIteratorBase<T> {
+    template<typename T, size_t inlineCapacity>
+    class DequeConstIterator : public DequeIteratorBase<T, inlineCapacity> {
     private:
-        typedef DequeIteratorBase<T> Base;
-        typedef DequeConstIterator<T> Iterator;
-        typedef DequeIterator<T> NonConstIterator;
+        typedef DequeIteratorBase<T, inlineCapacity> Base;
+        typedef DequeConstIterator<T, inlineCapacity> Iterator;
+        typedef DequeIterator<T, inlineCapacity> NonConstIterator;
 
     public:
         typedef ptrdiff_t difference_type;
@@ -193,7 +194,8 @@ namespace WTF {
         typedef const T& reference;
         typedef std::bidirectional_iterator_tag iterator_category;
 
-        DequeConstIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
+        DequeConstIterator(const Deque<T, inlineCapacity>* deque, size_t index)
+            : Base(deque, index) { }
 
         DequeConstIterator(const Iterator& other) : Base(other) { }
         DequeConstIterator(const NonConstIterator& other) : Base(other) { }
@@ -213,12 +215,12 @@ namespace WTF {
     };
 
 #ifdef NDEBUG
-    template<typename T> inline void Deque<T>::checkValidity() const { }
-    template<typename T> inline void Deque<T>::checkIndexValidity(size_t) const { }
-    template<typename T> inline void Deque<T>::invalidateIterators() { }
+    template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkValidity() const { }
+    template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkIndexValidity(size_t) const { }
+    template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::invalidateIterators() { }
 #else
-    template<typename T>
-    void Deque<T>::checkValidity() const
+    template<typename T, size_t inlineCapacity>
+    void Deque<T, inlineCapacity>::checkValidity() const
     {
         // In this implementation a capacity of 1 would confuse append() and
         // other places that assume the index after capacity - 1 is 0.
@@ -233,8 +235,8 @@ namespace WTF {
         }
     }
 
-    template<typename T>
-    void Deque<T>::checkIndexValidity(size_t index) const
+    template<typename T, size_t inlineCapacity>
+    void Deque<T, inlineCapacity>::checkIndexValidity(size_t index) const
     {
         ASSERT_UNUSED(index, index <= m_buffer.capacity());
         if (m_start <= m_end) {
@@ -245,8 +247,8 @@ namespace WTF {
         }
     }
 
-    template<typename T>
-    void Deque<T>::invalidateIterators()
+    template<typename T, size_t inlineCapacity>
+    void Deque<T, inlineCapacity>::invalidateIterators()
     {
         IteratorBase* next;
         for (IteratorBase* p = m_iterators; p; p = next) {
@@ -259,8 +261,8 @@ namespace WTF {
     }
 #endif
 
-    template<typename T>
-    inline Deque<T>::Deque()
+    template<typename T, size_t inlineCapacity>
+    inline Deque<T, inlineCapacity>::Deque()
         : m_start(0)
         , m_end(0)
 #ifndef NDEBUG
@@ -270,8 +272,8 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline Deque<T>::Deque(const Deque<T>& other)
+    template<typename T, size_t inlineCapacity>
+    inline Deque<T, inlineCapacity>::Deque(const Deque<T, inlineCapacity>& other)
         : m_start(other.m_start)
         , m_end(other.m_end)
         , m_buffer(other.m_buffer.capacity())
@@ -288,18 +290,18 @@ namespace WTF {
         }
     }
 
-    template<typename T>
-    inline Deque<T>& Deque<T>::operator=(const Deque<T>& other)
+    template<typename T, size_t inlineCapacity>
+    inline Deque<T, inlineCapacity>& Deque<T, inlineCapacity>::operator=(const Deque<T, inlineCapacity>& other)
     {
         // FIXME: This is inefficient if we're using an inline buffer and T is
         // expensive to copy since it will copy the buffer twice instead of once.
-        Deque<T> copy(other);
+        Deque<T, inlineCapacity> copy(other);
         swap(copy);
         return *this;
     }
 
-    template<typename T>
-    inline void Deque<T>::destroyAll()
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::destroyAll()
     {
         if (m_start <= m_end)
             TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end);
@@ -309,16 +311,16 @@ namespace WTF {
         }
     }
 
-    template<typename T>
-    inline Deque<T>::~Deque()
+    template<typename T, size_t inlineCapacity>
+    inline Deque<T, inlineCapacity>::~Deque()
     {
         checkValidity();
         invalidateIterators();
         destroyAll();
     }
 
-    template<typename T>
-    inline void Deque<T>::swap(Deque<T>& other)
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::swap(Deque<T, inlineCapacity>& other)
     {
         checkValidity();
         other.checkValidity();
@@ -330,8 +332,8 @@ namespace WTF {
         other.checkValidity();
     }
 
-    template<typename T>
-    inline void Deque<T>::clear()
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::clear()
     {
         checkValidity();
         invalidateIterators();
@@ -342,9 +344,9 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
+    template<typename T, size_t inlineCapacity>
     template<typename Predicate>
-    inline auto Deque<T>::findIf(Predicate&& predicate) -> iterator
+    inline auto Deque<T, inlineCapacity>::findIf(Predicate&& predicate) -> iterator
     {
         iterator end_iterator = end();
         for (iterator it = begin(); it != end_iterator; ++it) {
@@ -354,8 +356,8 @@ namespace WTF {
         return end_iterator;
     }
 
-    template<typename T>
-    inline void Deque<T>::expandCapacityIfNeeded()
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::expandCapacityIfNeeded()
     {
         if (m_start) {
             if (m_end + 1 != m_start)
@@ -369,8 +371,8 @@ namespace WTF {
         expandCapacity();
     }
 
-    template<typename T>
-    void Deque<T>::expandCapacity()
+    template<typename T, size_t inlineCapacity>
+    void Deque<T, inlineCapacity>::expandCapacity()
     {
         checkValidity();
         size_t oldCapacity = m_buffer.capacity();
@@ -388,24 +390,24 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline auto Deque<T>::takeFirst() -> T
+    template<typename T, size_t inlineCapacity>
+    inline auto Deque<T, inlineCapacity>::takeFirst() -> T
     {
         T oldFirst = std::move(first());
         removeFirst();
         return oldFirst;
     }
 
-    template<typename T>
-    inline auto Deque<T>::takeLast() -> T
+    template<typename T, size_t inlineCapacity>
+    inline auto Deque<T, inlineCapacity>::takeLast() -> T
     {
         T oldLast = std::move(last());
         removeLast();
         return oldLast;
     }
 
-    template<typename T> template<typename U>
-    inline void Deque<T>::append(U&& value)
+    template<typename T, size_t inlineCapacity> template<typename U>
+    inline void Deque<T, inlineCapacity>::append(U&& value)
     {
         checkValidity();
         expandCapacityIfNeeded();
@@ -417,8 +419,8 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T> template<typename U>
-    inline void Deque<T>::prepend(U&& value)
+    template<typename T, size_t inlineCapacity> template<typename U>
+    inline void Deque<T, inlineCapacity>::prepend(U&& value)
     {
         checkValidity();
         expandCapacityIfNeeded();
@@ -430,8 +432,8 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline void Deque<T>::removeFirst()
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::removeFirst()
     {
         checkValidity();
         invalidateIterators();
@@ -444,8 +446,8 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline void Deque<T>::removeLast()
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::removeLast()
     {
         checkValidity();
         invalidateIterators();
@@ -458,22 +460,22 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline void Deque<T>::remove(iterator& it)
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::remove(iterator& it)
     {
         it.checkValidity();
         remove(it.m_index);
     }
 
-    template<typename T>
-    inline void Deque<T>::remove(const_iterator& it)
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::remove(const_iterator& it)
     {
         it.checkValidity();
         remove(it.m_index);
     }
 
-    template<typename T>
-    inline void Deque<T>::remove(size_t position)
+    template<typename T, size_t inlineCapacity>
+    inline void Deque<T, inlineCapacity>::remove(size_t position)
     {
         if (position == m_end)
             return;
@@ -496,28 +498,28 @@ namespace WTF {
     }
 
 #ifdef NDEBUG
-    template<typename T> inline void DequeIteratorBase<T>::checkValidity() const { }
-    template<typename T> inline void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase<T>&) const { }
-    template<typename T> inline void DequeIteratorBase<T>::addToIteratorsList() { }
-    template<typename T> inline void DequeIteratorBase<T>::removeFromIteratorsList() { }
+    template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity() const { }
+    template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase<T, inlineCapacity>&) const { }
+    template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList() { }
+    template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList() { }
 #else
-    template<typename T>
-    void DequeIteratorBase<T>::checkValidity() const
+    template<typename T, size_t inlineCapacity>
+    void DequeIteratorBase<T, inlineCapacity>::checkValidity() const
     {
         ASSERT(m_deque);
         m_deque->checkIndexValidity(m_index);
     }
 
-    template<typename T>
-    void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase& other) const
+    template<typename T, size_t inlineCapacity>
+    void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase& other) const
     {
         checkValidity();
         other.checkValidity();
         ASSERT(m_deque == other.m_deque);
     }
 
-    template<typename T>
-    void DequeIteratorBase<T>::addToIteratorsList()
+    template<typename T, size_t inlineCapacity>
+    void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList()
     {
         if (!m_deque)
             m_next = 0;
@@ -530,8 +532,8 @@ namespace WTF {
         m_previous = 0;
     }
 
-    template<typename T>
-    void DequeIteratorBase<T>::removeFromIteratorsList()
+    template<typename T, size_t inlineCapacity>
+    void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList()
     {
         if (!m_deque) {
             ASSERT(!m_next);
@@ -555,23 +557,23 @@ namespace WTF {
     }
 #endif
 
-    template<typename T>
-    inline DequeIteratorBase<T>::DequeIteratorBase()
+    template<typename T, size_t inlineCapacity>
+    inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase()
         : m_deque(0)
     {
     }
 
-    template<typename T>
-    inline DequeIteratorBase<T>::DequeIteratorBase(const Deque<T>* deque, size_t index)
-        : m_deque(const_cast<Deque<T>*>(deque))
+    template<typename T, size_t inlineCapacity>
+    inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Deque<T, inlineCapacity>* deque, size_t index)
+        : m_deque(const_cast<Deque<T, inlineCapacity>*>(deque))
         , m_index(index)
     {
         addToIteratorsList();
         checkValidity();
     }
 
-    template<typename T>
-    inline DequeIteratorBase<T>::DequeIteratorBase(const DequeIteratorBase& other)
+    template<typename T, size_t inlineCapacity>
+    inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const DequeIteratorBase& other)
         : m_deque(other.m_deque)
         , m_index(other.m_index)
     {
@@ -579,8 +581,8 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline DequeIteratorBase<T>& DequeIteratorBase<T>::operator=(const DequeIteratorBase& other)
+    template<typename T, size_t inlineCapacity>
+    inline DequeIteratorBase<T, inlineCapacity>& DequeIteratorBase<T, inlineCapacity>::operator=(const DequeIteratorBase& other)
     {
         other.checkValidity();
         removeFromIteratorsList();
@@ -592,8 +594,8 @@ namespace WTF {
         return *this;
     }
 
-    template<typename T>
-    inline DequeIteratorBase<T>::~DequeIteratorBase()
+    template<typename T, size_t inlineCapacity>
+    inline DequeIteratorBase<T, inlineCapacity>::~DequeIteratorBase()
     {
 #ifndef NDEBUG
         removeFromIteratorsList();
@@ -601,15 +603,15 @@ namespace WTF {
 #endif
     }
 
-    template<typename T>
-    inline bool DequeIteratorBase<T>::isEqual(const DequeIteratorBase& other) const
+    template<typename T, size_t inlineCapacity>
+    inline bool DequeIteratorBase<T, inlineCapacity>::isEqual(const DequeIteratorBase& other) const
     {
         checkValidity(other);
         return m_index == other.m_index;
     }
 
-    template<typename T>
-    inline void DequeIteratorBase<T>::increment()
+    template<typename T, size_t inlineCapacity>
+    inline void DequeIteratorBase<T, inlineCapacity>::increment()
     {
         checkValidity();
         ASSERT(m_index != m_deque->m_end);
@@ -621,8 +623,8 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline void DequeIteratorBase<T>::decrement()
+    template<typename T, size_t inlineCapacity>
+    inline void DequeIteratorBase<T, inlineCapacity>::decrement()
     {
         checkValidity();
         ASSERT(m_index != m_deque->m_start);
@@ -634,16 +636,16 @@ namespace WTF {
         checkValidity();
     }
 
-    template<typename T>
-    inline T* DequeIteratorBase<T>::after() const
+    template<typename T, size_t inlineCapacity>
+    inline T* DequeIteratorBase<T, inlineCapacity>::after() const
     {
         checkValidity();
         ASSERT(m_index != m_deque->m_end);
         return &m_deque->m_buffer.buffer()[m_index];
     }
 
-    template<typename T>
-    inline T* DequeIteratorBase<T>::before() const
+    template<typename T, size_t inlineCapacity>
+    inline T* DequeIteratorBase<T, inlineCapacity>::before() const
     {
         checkValidity();
         ASSERT(m_index != m_deque->m_start);
index 47907ba..5394e0a 100644 (file)
@@ -1,3 +1,25 @@
+2014-07-01  Alex Christensen  <achristensen@webkit.org>
+
+        Reduce dynamic memory allocation in css jit.
+        https://bugs.webkit.org/show_bug.cgi?id=134416
+
+        Reviewed by Benjamin Poulain.
+
+        * cssjit/FunctionCall.h:
+        (WebCore::FunctionCall::saveAllocatedRegisters):
+        * cssjit/RegisterAllocator.h:
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::addPseudoClassType):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+        * cssjit/StackAllocator.h:
+        (WebCore::StackAllocator::push):
+        (WebCore::StackAllocator::pop):
+        Use inlineCapacity template parameter to reduce malloc calls.
+        I use 32 as the inline capacity for non-register related vectors because that
+        is probably big enough for the selector compiler, and if it is not then a malloc
+        call will not be significant because the selector is very complex.
+
 2014-07-01  Eric Carlson  <eric.carlson@apple.com>
 
         WebVTT percentage value can be a float
index dedb319..033979f 100644 (file)
@@ -37,7 +37,7 @@ namespace WebCore {
 
 class FunctionCall {
 public:
-    FunctionCall(JSC::MacroAssembler& assembler, RegisterAllocator& registerAllocator, StackAllocator& stackAllocator, Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>>& callRegistry)
+    FunctionCall(JSC::MacroAssembler& assembler, RegisterAllocator& registerAllocator, StackAllocator& stackAllocator, Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>, 32>& callRegistry)
         : m_assembler(assembler)
         , m_registerAllocator(registerAllocator)
         , m_stackAllocator(stackAllocator)
@@ -167,7 +167,7 @@ private:
             if (RegisterAllocator::isCallerSavedRegister(registerID))
                 m_savedRegisters.append(registerID);
         }
-        Vector<StackAllocator::StackReference> stackReferences = m_stackAllocator.push(m_savedRegisters);
+        Vector<StackAllocator::StackReference, registerCount> stackReferences = m_stackAllocator.push(m_savedRegisters);
         m_savedRegisterStackReferences.appendVector(stackReferences);
     }
 
@@ -180,7 +180,7 @@ private:
     JSC::MacroAssembler& m_assembler;
     RegisterAllocator& m_registerAllocator;
     StackAllocator& m_stackAllocator;
-    Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>>& m_callRegistry;
+    Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>, 32>& m_callRegistry;
 
     Vector<JSC::MacroAssembler::RegisterID, registerCount> m_savedRegisters;
     Vector<StackAllocator::StackReference, registerCount> m_savedRegisterStackReferences;
index 73d64ed..0d1297a 100644 (file)
@@ -205,7 +205,7 @@ public:
     }
 
 private:
-    Deque<JSC::MacroAssembler::RegisterID> m_registers;
+    Deque<JSC::MacroAssembler::RegisterID, registerCount> m_registers;
     Vector<JSC::MacroAssembler::RegisterID, registerCount> m_allocatedRegisters;
     Vector<JSC::MacroAssembler::RegisterID, calleeSavedRegisterCount> m_reservedCalleeSavedRegisters;
 };
index f5314f7..b9802bb 100644 (file)
@@ -159,11 +159,11 @@ struct SelectorFragment {
     const QualifiedName* tagName;
     const AtomicString* id;
     const AtomicString* langFilter;
-    Vector<const AtomicStringImpl*, 1> classNames;
+    Vector<const AtomicStringImpl*, 32> classNames;
     HashSet<unsigned> pseudoClasses;
-    Vector<JSC::FunctionPtr> unoptimizedPseudoClasses;
-    Vector<AttributeMatchingInfo> attributes;
-    Vector<std::pair<int, int>> nthChildFilters;
+    Vector<JSC::FunctionPtr, 32> unoptimizedPseudoClasses;
+    Vector<AttributeMatchingInfo, 32> attributes;
+    Vector<std::pair<int, int>, 32> nthChildFilters;
     Vector<SelectorFragment> notFilters;
     Vector<Vector<SelectorFragment>> anyFilters;
 
@@ -192,8 +192,8 @@ struct TagNamePattern {
 };
 
 typedef JSC::MacroAssembler Assembler;
-typedef Vector<SelectorFragment, 8> SelectorFragmentList;
-typedef Vector<TagNamePattern, 8> TagNameList;
+typedef Vector<SelectorFragment, 32> SelectorFragmentList;
+typedef Vector<TagNamePattern, 32> TagNameList;
 
 class SelectorCodeGenerator {
 public:
@@ -265,12 +265,12 @@ private:
 
     bool generatePrologue();
     void generateEpilogue();
-    Vector<StackAllocator::StackReference> m_prologueStackReferences;
+    Vector<StackAllocator::StackReference, registerCount> m_prologueStackReferences;
 
     Assembler m_assembler;
     RegisterAllocator m_registerAllocator;
     StackAllocator m_stackAllocator;
-    Vector<std::pair<Assembler::Call, JSC::FunctionPtr>> m_functionCalls;
+    Vector<std::pair<Assembler::Call, JSC::FunctionPtr>, 32> m_functionCalls;
 
     SelectorContext m_selectorContext;
     FunctionType m_functionType;
@@ -476,7 +476,7 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec
 
     case CSSSelector::PseudoClassAny:
         {
-            Vector<SelectorFragment> anyFragments;
+            Vector<SelectorFragment, 32> anyFragments;
             FunctionType functionType = FunctionType::SimpleSelectorChecker;
             for (const CSSSelector* rootSelector = selector.selectorList()->first(); rootSelector; rootSelector = CSSSelectorList::next(rootSelector)) {
                 SelectorFragmentList fragmentList;
@@ -1166,7 +1166,7 @@ inline void SelectorCodeGenerator::generateEpilogue()
 
 void SelectorCodeGenerator::generateSelectorChecker()
 {
-    Vector<StackAllocator::StackReference> calleeSavedRegisterStackReferences;
+    Vector<StackAllocator::StackReference, calleeSavedRegisterCount> calleeSavedRegisterStackReferences;
     bool reservedCalleeSavedRegisters = false;
     unsigned availableRegisterCount = m_registerAllocator.availableRegisterCount();
     unsigned minimumRegisterCountForAttributes = minimumRegisterRequirements(m_selectorFragments);
@@ -2582,7 +2582,7 @@ void SelectorCodeGenerator::generateElementIsNthChild(Assembler::JumpList& failu
     Assembler::RegisterID parentElement = m_registerAllocator.allocateRegister();
     generateWalkToParentElement(failureCases, parentElement);
 
-    Vector<std::pair<int, int>> validSubsetFilters;
+    Vector<std::pair<int, int>, 32> validSubsetFilters;
     validSubsetFilters.reserveInitialCapacity(fragment.nthChildFilters.size());
     for (const auto& slot : fragment.nthChildFilters) {
         int a = slot.first;
index 10cdbfe..8a74eaa 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(CSS_SELECTOR_JIT)
 
+#include "RegisterAllocator.h"
 #include <JavaScriptCore/MacroAssembler.h>
 
 namespace WebCore {
@@ -68,21 +69,20 @@ public:
         return StackReference(m_offsetFromTop);
     }
 
-    Vector<StackReference> push(const Vector<JSC::MacroAssembler::RegisterID>& registerIDs)
+    Vector<StackReference, registerCount> push(const Vector<JSC::MacroAssembler::RegisterID>& registerIDs)
     {
         RELEASE_ASSERT(!m_hasFunctionCallPadding);
-        unsigned registerCount = registerIDs.size();
-        Vector<StackReference> stackReferences;
-        stackReferences.reserveInitialCapacity(registerCount);
+        Vector<StackReference, registerCount> stackReferences;
 #if CPU(ARM64)
-        for (unsigned i = 0; i < registerCount - 1; i += 2) {
+        unsigned pushRegisterCount = registerIDs.size();
+        for (unsigned i = 0; i < pushRegisterCount - 1; i += 2) {
             m_assembler.pushPair(registerIDs[i + 1], registerIDs[i]);
             m_offsetFromTop += stackUnitInBytes();
             stackReferences.append(StackReference(m_offsetFromTop - stackUnitInBytes() / 2));
             stackReferences.append(StackReference(m_offsetFromTop));
         }
-        if (registerCount % 2)
-            stackReferences.append(push(registerIDs[registerCount - 1]));
+        if (pushRegisterCount % 2)
+            stackReferences.append(push(registerIDs[pushRegisterCount - 1]));
 #else
         for (auto registerID : registerIDs)
             stackReferences.append(push(registerID));
@@ -102,14 +102,14 @@ public:
     {
         RELEASE_ASSERT(!m_hasFunctionCallPadding);
 
-        unsigned registerCount = registerIDs.size();
-        RELEASE_ASSERT(stackReferences.size() == registerCount);
+        unsigned popRegisterCount = registerIDs.size();
+        RELEASE_ASSERT(stackReferences.size() == popRegisterCount);
 #if CPU(ARM64)
-        ASSERT(m_offsetFromTop >= stackUnitInBytes() * ((registerCount + 1) / 2));
-        unsigned registerCountOdd = registerCount % 2;
-        if (registerCountOdd)
-            pop(stackReferences[registerCount - 1], registerIDs[registerCount - 1]);
-        for (unsigned i = registerCount - registerCountOdd; i > 0; i -= 2) {
+        ASSERT(m_offsetFromTop >= stackUnitInBytes() * ((popRegisterCount + 1) / 2));
+        unsigned popRegisterCountOdd = popRegisterCount % 2;
+        if (popRegisterCountOdd)
+            pop(stackReferences[popRegisterCount - 1], registerIDs[popRegisterCount - 1]);
+        for (unsigned i = popRegisterCount - popRegisterCountOdd; i > 0; i -= 2) {
             RELEASE_ASSERT(stackReferences[i - 1] == m_offsetFromTop);
             RELEASE_ASSERT(stackReferences[i - 2] == m_offsetFromTop - stackUnitInBytes() / 2);
             RELEASE_ASSERT(m_offsetFromTop >= stackUnitInBytes());
@@ -117,8 +117,8 @@ public:
             m_assembler.popPair(registerIDs[i - 1], registerIDs[i - 2]);
         }
 #else
-        ASSERT(m_offsetFromTop >= stackUnitInBytes() * registerCount);
-        for (unsigned i = registerCount; i > 0; --i)
+        ASSERT(m_offsetFromTop >= stackUnitInBytes() * popRegisterCount);
+        for (unsigned i = popRegisterCount; i > 0; --i)
             pop(stackReferences[i - 1], registerIDs[i - 1]);
 #endif
     }