Title: [169953] trunk/Source/WebCore
Revision
169953
Author
[email protected]
Date
2014-06-13 15:26:52 -0700 (Fri, 13 Jun 2014)

Log Message

Make css jit allocator smarter.
https://bugs.webkit.org/show_bug.cgi?id=133834

Patch by Alex Christensen <[email protected]> on 2014-06-13
Reviewed by Benjamin Poulain.

* cssjit/RegisterAllocator.h:
(WebCore::RegisterAllocator::allocateRegister):
(WebCore::RegisterAllocator::deallocateRegister):
(WebCore::RegisterAllocator::reserveCalleeSavedRegisters):
(WebCore::LocalRegister::LocalRegister):
(WebCore::RegisterAllocator::RegisterAllocator):
Use a Deque for the registers.  Allocate from the front and deallocate to the back to cycle the register usage.
(WebCore::RegisterAllocator::allocateRegisterWithPreference):
(WebCore::LocalRegisterWithPreference::LocalRegisterWithPreference):
Added the ability to specify that we prefer a certain register if it is available while allocating.
These functions always return a register.  It is just a different register than preferred if the preferred register is not available.
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeValueExactMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsActive):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
Whenever we are allocating a register for the second argument, we should specify that we
prefer to have argumentGPR1 to reduce register swapping when preparing for a function call.
This cannot be done for argumentGPR0 because elementAddressRegister is argumentGPR0 and it is always allocated.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (169952 => 169953)


--- trunk/Source/WebCore/ChangeLog	2014-06-13 22:24:17 UTC (rev 169952)
+++ trunk/Source/WebCore/ChangeLog	2014-06-13 22:26:52 UTC (rev 169953)
@@ -1,3 +1,31 @@
+2014-06-13  Alex Christensen  <[email protected]>
+
+        Make css jit allocator smarter.
+        https://bugs.webkit.org/show_bug.cgi?id=133834
+
+        Reviewed by Benjamin Poulain.
+
+        * cssjit/RegisterAllocator.h:
+        (WebCore::RegisterAllocator::allocateRegister):
+        (WebCore::RegisterAllocator::deallocateRegister):
+        (WebCore::RegisterAllocator::reserveCalleeSavedRegisters):
+        (WebCore::LocalRegister::LocalRegister):
+        (WebCore::RegisterAllocator::RegisterAllocator):
+        Use a Deque for the registers.  Allocate from the front and deallocate to the back to cycle the register usage.
+        (WebCore::RegisterAllocator::allocateRegisterWithPreference):
+        (WebCore::LocalRegisterWithPreference::LocalRegisterWithPreference):
+        Added the ability to specify that we prefer a certain register if it is available while allocating.
+        These functions always return a register.  It is just a different register than preferred if the preferred register is not available.
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeValueExactMatching):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsActive):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+        Whenever we are allocating a register for the second argument, we should specify that we 
+        prefer to have argumentGPR1 to reduce register swapping when preparing for a function call.
+        This cannot be done for argumentGPR0 because elementAddressRegister is argumentGPR0 and it is always allocated.
+
 2014-06-13  Jeremy Jones  <[email protected]>
 
         set setUsesExternalPlaybackWhileExternalScreenIsActive based on fullscreen mode

Modified: trunk/Source/WebCore/cssjit/RegisterAllocator.h (169952 => 169953)


--- trunk/Source/WebCore/cssjit/RegisterAllocator.h	2014-06-13 22:24:17 UTC (rev 169952)
+++ trunk/Source/WebCore/cssjit/RegisterAllocator.h	2014-06-13 22:26:52 UTC (rev 169953)
@@ -29,7 +29,7 @@
 #if ENABLE(CSS_SELECTOR_JIT)
 
 #include <_javascript_Core/MacroAssembler.h>
-#include <wtf/HashSet.h>
+#include <wtf/Deque.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -102,9 +102,9 @@
 
     JSC::MacroAssembler::RegisterID allocateRegister()
     {
-        auto first = m_registers.begin();
-        JSC::MacroAssembler::RegisterID registerID = static_cast<JSC::MacroAssembler::RegisterID>(*first);
-        RELEASE_ASSERT(m_registers.remove(first));
+        RELEASE_ASSERT(m_registers.size());
+        JSC::MacroAssembler::RegisterID registerID = m_registers.first();
+        m_registers.removeFirst();
         ASSERT(!m_allocatedRegisters.contains(registerID));
         m_allocatedRegisters.append(registerID);
         return registerID;
@@ -112,10 +112,29 @@
 
     void allocateRegister(JSC::MacroAssembler::RegisterID registerID)
     {
-        RELEASE_ASSERT(m_registers.remove(registerID));
-        ASSERT(!m_allocatedRegisters.contains(registerID));
-        m_allocatedRegisters.append(registerID);
+        for (auto it = m_registers.begin(); it != m_registers.end(); ++it) {
+            if (*it == registerID) {
+                m_registers.remove(it);
+                ASSERT(!m_allocatedRegisters.contains(registerID));
+                m_allocatedRegisters.append(registerID);
+                return;
+            }
+        }
+        RELEASE_ASSERT_NOT_REACHED();
     }
+    
+    JSC::MacroAssembler::RegisterID allocateRegisterWithPreference(JSC::MacroAssembler::RegisterID preferredRegister)
+    {
+        for (auto it = m_registers.begin(); it != m_registers.end(); ++it) {
+            if (*it == preferredRegister) {
+                m_registers.remove(it);
+                ASSERT(!m_allocatedRegisters.contains(preferredRegister));
+                m_allocatedRegisters.append(preferredRegister);
+                return preferredRegister;
+            }
+        }
+        return allocateRegister();
+    }
 
     void deallocateRegister(JSC::MacroAssembler::RegisterID registerID)
     {
@@ -123,7 +142,9 @@
         // Most allocation/deallocation happen in stack-like order. In the common case, this
         // just removes the last item.
         m_allocatedRegisters.remove(m_allocatedRegisters.reverseFind(registerID));
-        RELEASE_ASSERT(m_registers.add(registerID).isNewEntry);
+        for (auto unallocatedRegister : m_registers)
+            RELEASE_ASSERT(unallocatedRegister != registerID);
+        m_registers.append(registerID);
     }
 
     const Vector<JSC::MacroAssembler::RegisterID, calleeSavedRegisterCount>& reserveCalleeSavedRegisters(unsigned count)
@@ -133,7 +154,7 @@
         for (unsigned i = 0; i < count; ++i) {
             JSC::MacroAssembler::RegisterID registerId = calleeSavedRegisters[i];
             m_reservedCalleeSavedRegisters.append(registerId);
-            m_registers.add(registerId);
+            m_registers.append(registerId);
         }
         return m_reservedCalleeSavedRegisters;
     }
@@ -161,7 +182,7 @@
     }
 
 private:
-    HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_registers;
+    Deque<JSC::MacroAssembler::RegisterID> m_registers;
     Vector<JSC::MacroAssembler::RegisterID, registerCount> m_allocatedRegisters;
     Vector<JSC::MacroAssembler::RegisterID, calleeSavedRegisterCount> m_reservedCalleeSavedRegisters;
 };
@@ -184,15 +205,28 @@
         return m_register;
     }
 
-private:
+protected:
+    explicit LocalRegister(RegisterAllocator& allocator, JSC::MacroAssembler::RegisterID registerID)
+        : m_allocator(allocator)
+        , m_register(registerID)
+    {
+    }
     RegisterAllocator& m_allocator;
     JSC::MacroAssembler::RegisterID m_register;
 };
 
+class LocalRegisterWithPreference : public LocalRegister {
+public:
+    explicit LocalRegisterWithPreference(RegisterAllocator& allocator, JSC::MacroAssembler::RegisterID preferredRegister)
+        : LocalRegister(allocator, allocator.allocateRegisterWithPreference(preferredRegister))
+    {
+    }
+};
+    
 inline RegisterAllocator::RegisterAllocator()
 {
     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(callerSavedRegisters); ++i)
-        m_registers.add(callerSavedRegisters[i]);
+        m_registers.append(callerSavedRegisters[i]);
 }
 
 inline RegisterAllocator::~RegisterAllocator()

Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (169952 => 169953)


--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2014-06-13 22:24:17 UTC (rev 169952)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2014-06-13 22:26:52 UTC (rev 169953)
@@ -2064,7 +2064,7 @@
 
 void SelectorCodeGenerator::generateElementAttributeValueExactMatching(Assembler::JumpList& failureCases, Assembler::RegisterID currentAttributeAddress, const AtomicString& expectedValue, bool canDefaultToCaseSensitiveValueMatch)
 {
-    LocalRegister expectedValueRegister(m_registerAllocator);
+    LocalRegisterWithPreference expectedValueRegister(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
     m_assembler.move(Assembler::TrustedImmPtr(expectedValue.impl()), expectedValueRegister);
 
     if (canDefaultToCaseSensitiveValueMatch)
@@ -2088,7 +2088,7 @@
 
         FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
         functionCall.setFunctionAddress(WTF::equalIgnoringCaseNonNull);
-        functionCall.setTwoArguments(expectedValueRegister, valueStringImpl);
+        functionCall.setTwoArguments(valueStringImpl, expectedValueRegister);
         failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
 
         skipCaseInsensitiveComparison.link(&m_assembler);
@@ -2097,7 +2097,7 @@
 
 void SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching(Assembler::JumpList& failureCases, Assembler::RegisterID currentAttributeAddress, const AtomicString& expectedValue, bool canDefaultToCaseSensitiveValueMatch, JSC::FunctionPtr caseSensitiveTest, JSC::FunctionPtr caseInsensitiveTest)
 {
-    LocalRegister expectedValueRegister(m_registerAllocator);
+    LocalRegisterWithPreference expectedValueRegister(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
     m_assembler.move(Assembler::TrustedImmPtr(expectedValue.impl()), expectedValueRegister);
 
     if (canDefaultToCaseSensitiveValueMatch) {
@@ -2186,7 +2186,7 @@
             failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
         } else {
             unsigned offsetToCheckingContext = m_stackAllocator.offsetToStackReference(m_checkingContextStackReference);
-            Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegister();
+            Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1);
             m_assembler.loadPtr(Assembler::Address(Assembler::stackPointerRegister, offsetToCheckingContext), checkingContext);
             m_registerAllocator.deallocateRegister(checkingContext);
 
@@ -2271,7 +2271,7 @@
         failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
     } else {
         if (fragment.relationToRightFragment == FragmentRelation::Rightmost) {
-            LocalRegister checkingContext(m_registerAllocator);
+            LocalRegisterWithPreference checkingContext(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
             Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext);
             addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::flagIsaffectedByHover());
             notResolvingStyle.link(&m_assembler);
@@ -2282,7 +2282,7 @@
             failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
         } else {
             unsigned offsetToCheckingContext = m_stackAllocator.offsetToStackReference(m_checkingContextStackReference);
-            Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegister();
+            Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1);
             m_assembler.loadPtr(Assembler::Address(Assembler::stackPointerRegister, offsetToCheckingContext), checkingContext);
             m_registerAllocator.deallocateRegister(checkingContext);
 
@@ -2542,7 +2542,7 @@
         m_registerAllocator.deallocateRegister(parentElement);
 
     // Setup the counter at 1.
-    LocalRegister elementCounter(m_registerAllocator);
+    LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
     m_assembler.move(Assembler::TrustedImm32(1), elementCounter);
 
     // Loop over the previous adjacent elements and increment the counter.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to